Case Study - One grocery list your whole household shares
A real-time shared grocery list with household chat — deliberately minimal, offline-capable, and identical on web, iOS and Android. Live at gema.spectralgo.com.
- Project
- Gema
- Year
- Service
- Product engineering, mobile & web
- Live at
- gema.spectralgo.com ↗
GemaMSOverview
Gema is one grocery list your whole household shares: you add eggs, and it's on everyone else's phone before yours is back in your pocket. It pairs the list with a built-in household chat — mentions, presence, typing indicators, pinned messages — so coordinating the shopping feels like a conversation, not a chore. It's live at gema.spectralgo.com on web, iOS and Android.
The product is deliberately minimal — no ads, no macro-tracking meal-plan-coach detour. It's a list, it syncs, it's free. AI stays in a supporting role: natural-language item parsing and store suggestions, not a chatbot. The personality comes from eggy, the winking mascot, and small delights like the confetti that rains when someone checks off a salad.
One list, four views: by item, by store (via #store tags), by person (via @mentions, so assignments are just text), and a bonus “To Watch” view where anything tagged #movie or #tv lands instead of the shopping list.
The next chapter: chat that plans for you
In development is where the chat and the list truly meet. Mention @Gema in the household chat — “taco night Friday, add what we need” — and Gema puts the event on a shared calendar and proposes the shopping list to prep it. Nothing is written silently: a household member approves the items before they land on the list, which keeps the assistant useful without letting it take over. It's the same restraint as the rest of the product — AI that drafts, humans that decide.
What we did
- Real-time sync (Durable Objects + WebSockets)
- Offline outbox & optimistic updates
- React web + React Native (Expo)
- Hono + oRPC on Cloudflare Workers
- AI item parsing (Gemini)
- i18n: English, French, Portuguese
Web/native parity is a discipline, not a framework feature. Gema's sync engine is shared code, audited feature-by-feature across platforms, and every realtime edge case ships with a recorded proof.
Engineering notes
Every list and every chat room is its own Cloudflare Durable Object with embedded SQLite, so real-time state lives next to the users who share it; D1 holds the relational core. A shared sync package gives web and native the same offline mutation queue, reconnection logic and optimistic updates — the parity audit covers 70+ features across both platforms, and realtime edge cases (offline adds, reconnect deletes, conflicts) are verified with recorded proofs. Every pull request deploys its own isolated preview stage.