Back to Projects

Grocery Voice

A voice-first iOS grocery app: say your list out loud and AI turns it into an organized, aisle-ready list — then sends it straight to your real Kroger cart. Built end to end in a week.

July 5, 2026
React NativeExpoNext.jstRPCPostgreSQLClaude AIKroger APIVercel

What Is Grocery Voice?

Grocery Voice started with a small annoyance: every grocery app makes you type. I wanted to say "two pounds of chicken, a dozen eggs, and whatever I need for tacos" while my hands were busy, and have a real list appear — quantities parsed, items grouped by aisle, and the taco ingredients inferred, not just transcribed. So I built exactly that.

Speech is transcribed on-device, Claude structures it into a categorized list, and if you shop at any Kroger banner (Ralphs, Fred Meyer, King Soopers…), one tap matches every item to real store products with live prices and pushes the whole list into your actual cart. It also generates dinner ideas from what you're buying — with per-serving nutrition estimates — and merges the missing ingredients back into your list.

It's live today: an iOS app in TestFlight beta (App Store review in progress), a full web app with feature parity at app.groceryvoice.app, and a marketing site. Real users, real carts, real groceries.

Key Features

  • Hands-free capture — talk naturally; recording ends when you pause and the list builds itself. A waveform shows it's listening, like a voice message.
  • Intent, not dictation — "whatever I need for tacos" becomes ground beef, shells, cheese, sour cream, lettuce, tomatoes.
  • Real cart handoff — Kroger OAuth, fuzzy product matching with a confirmation screen, live prices, one-tap push to your store's cart.
  • Recipes from your list — Claude suggests dinners from what you're buying and your stored preferences (dietary restrictions are a hard constraint), each with estimated macros.
  • Works in dead-zone aisles — lists are cached on-device; check-offs queue offline and sync when signal returns.
  • Three ways in — Sign in with Apple, email/password, or Discord, all invite-gated during early access, all sharing one session system across iOS and web.
Voice capture parsed into a categorized grocery listGenerated recipe with per-serving nutrition estimates

How It's Built

The backend is a T3 stack — Next.js 16, tRPC, Prisma, Postgres (Neon) — deployed on Vercel, with Claude doing the language work: Haiku parses transcripts into structured output, Opus generates recipes that self-catalog with cuisine tags and nutrition. The iOS app is React Native via Expo, sharing end-to-end types with the server through tRPC, with a fully non-interactive EAS build-and-submit pipeline to TestFlight. Mobile auth resolves bearer tokens against the same session rows NextAuth writes for the web, so one account works everywhere.

The Kroger integration was the fun part: their public tier is add-to-cart only, refresh tokens are single-use and rotate (the token store does optimistic rotation with a race-loser-adopts-winner strategy), and product search is fuzzy — which forced a match-confirmation UX that ended up being better than silent matching anyway. PostHog watches the product funnel (content-free by rule: counts and methods, never what anyone said), and Sentry watches for crashes — its first production catch found a session-expiry edge case on a beta tester's device the night before family onboarding.

The Meta-Story

I built this with AI pair-programming as a deliberate experiment: Claude Code wrote most of the code while I directed product decisions, caught bugs by using the app like a real person, and enforced a development loop — milestone plans, tests before merge, a decision log that turns every mistake into a rule. Idea to TestFlight took a weekend; idea to App Store submission took four days. The workflow itself became a reusable template I now bootstrap other projects with. It changed how I think about building software.