2026·E-commerce
Hunt Mart is a feature-rich storefront built on React and Vite, with Firebase for auth and product data and Algolia for search. Browse by category, search with typo tolerance, review ratings, scan a barcode, and check out — with cart state that stays consistent wherever you add or remove things.
What makes it worth writing up is a performance bug that took real digging. The search page froze under typing, and the cause was a feedback loop rather than anything to do with Algolia being slow.

Workflow decisions:
- Search state lives in the URL — Query, page and refinements route as /shop/search?q=laptop&page=2&category=beauty, so a result set is a shareable link and the back button behaves. Writes go through React Router's navigate, which keeps it the single owner of history.
- Widgets mount unconditionally — Mounting an InstantSearch widget calls addWidgets, which schedules another search. Rendering <Hits> only on the success path meant every resolved search fired a fresh one — about eight requests a second, forever. Now every widget registers up front and status only decides what is painted.
- query is never set on Configure — The query prop is reserved; InstantSearch owns it and routes it. Passing it anyway fought the router and duplicated work. Search goes through useSearchBox().refine() instead.
- Cart lives in one store — Zustand holds cart state globally, so any component reads and mutates it without prop drilling — add, decrement and remove all update the badge count immediately.

Architecture choices:
- Framework: React 19, Vite, React Router
- Search: Algolia, React InstantSearch
- State & data: Zustand, React Query, Axios
- Backend & auth: Firebase
- Styling: Tailwind CSS, Material UI, Emotion
- Quality: Vitest, Testing Library, ESLint, Husky
Impact:
- Typo-tolerant search finds a product from a word buried in its description.
- Results are shareable by copying the URL, and the back button works as expected.
- Cart totals, badge counts and quantity controls stay in sync across the app.
- A regression test asserts one request per query, so the freeze cannot silently return.
One security note worth repeating: nothing in a VITE_ variable is secret. Those values are inlined into the client bundle by definition, so the Algolia admin key is read by a seeding script and never by the app — data protection comes from Firebase Security Rules, not from withholding config.