Inspiration

We've all been there — scrolling through TikTok or YouTube, seeing an amazing recipe from Eitan Bernath, thinking "I need to make this." But then what? You screenshot the video, try to remember the ingredients at the grocery store, and inevitably forget half of them.

When I read Eitan's brief — "generate grocery lists from recipe video/link, organize saved recipes, and simplify cooking preparation" — it clicked immediately. His 2.3M followers don't just watch recipes for entertainment. They actually want to cook. The gap isn't discovery — Eitan already solves that. The gap is the journey from watching to cooking.

Cuisy bridges that gap. Paste a link, get a structured recipe, tap once to build your grocery list, and see exactly what you can cook with what's already in your fridge. No more screenshots. No more forgotten ingredients.

What it does

Cuisy turns recipe videos into action in three taps:

  1. Paste any recipe URL (YouTube, TikTok, Instagram) → AI extracts a fully structured recipe with ingredients, steps, cook times, and servings
  2. One tap → grocery list — missing ingredients are instantly added to a swipeable shopping list grouped by category (Produce, Dairy, Meat, Pantry, Bakery)
  3. Smart fridge matching — tell Cuisy what's in your fridge, and it shows you which saved recipes you can cook right now with a match percentage

Beyond the brief, Cuisy also offers:

  • Serving scaler — adjust portions and all quantities update automatically
  • Source filter & search — organize your growing recipe library by platform, name, or ingredients
  • Ready-to-Cook carousel — contextual suggestions based on time of day and available ingredients
  • Embedded video player — rewatch the original recipe video while cooking
  • Offline-first — everything works without internet; your recipe library lives on your device

Premium features (powered by RevenueCat):

  • Unlimited video parsing (free tier: 3/month)
  • PDF cookbook upload with AI-powered search
  • Meal photo recognition
  • Cloud sync across devices

How I built it

Frontend: Expo SDK 54 with React Native 0.81 and React 19, using the New Architecture (Fabric + TurboModules) from day one. Key libraries include react-native-reanimated for 60fps spring animations, @shopify/flash-list v2 for smooth recipe lists, @gorhom/bottom-sheet v5 for native-feeling interactions, and expo-haptics for tactile feedback on every meaningful touch.

Offline-first architecture was the most critical decision. I use SQLite (expo-sqlite) as the single source of truth with a repository pattern. Zustand stores provide instant UI updates, writing through to SQLite. For premium users, a fire-and-forget backend mirror syncs data asynchronously — it never blocks the UI.

User Action → Zustand (instant UI) → SQLite (persist) → Backend Mirror (premium, async)

Backend: Spring Boot 4 with PostgreSQL, handling video processing and AI extraction. The async job pipeline (PENDING → PROCESSING → COMPLETED) lets users keep browsing while recipes are being extracted.

Monetization: RevenueCat SDK handles subscriptions end-to-end — offerings, purchases, restore, and receipt validation. I built a multi-surface paywall system: a SoftPaywall bottom sheet that appears contextually when users hit a premium feature, a UsageMeter pill showing remaining free parses, and a full subscription screen with plan comparison.

Challenges I ran into

Multi-Platform Video Parsing

Each video platform required a completely different extraction strategy, which made the pipeline significantly more complex than expected.

YouTube uses a Python-based transcript extraction via youtube-transcript-api, but Google aggressively blocks datacenter IPs. I had to implement residential proxy rotation (Webshare) to keep extraction reliable. When transcripts are genuinely unavailable — no captions, non-English narration, music-heavy videos — the pipeline falls back to Gemini 2.0 Flash for native video understanding directly from the video frames.

TikTok & Instagram have no transcripts at all, so the approach is entirely video-native. I use yt-dlp to download the video (MP4, max 480p, 20MB cap), extract the post caption for context, and send both to Gemini 2.0 Flash's multimodal API. Gemini watches the video, reads on-screen text, and outputs a structured recipe. The challenge was consistency — a 15-second TikTok with flying text is very different from a calm YouTube tutorial, and the AI had to handle both reliably.

PDF Cookbook Search with RAG

Building a full RAG pipeline for cookbook search was one of the most challenging parts. The flow: Apache Tika extracts text from uploaded PDFs → intelligent chunking by recipe boundaries → OpenAI text-embedding-3-small generates vector embeddings → stored in pgvector (PostgreSQL) → at query time, user's fridge ingredients are embedded and matched via cosine similarity → retrieved chunks are synthesized into structured recipes by the LLM with source citations.

The hardest part was chunking — cookbooks don't follow consistent formatting, and bad chunks mean bad search results.

Offline-First with Eventual Sync

Every feature had to work without internet first, then optionally sync for premium users. This meant managing local IDs vs backend IDs, conflict resolution, and ensuring the UI never blocks on a network call. I built a backendMirror service that handles localId → backendId mapping and retries silently on failure.

Ingredient Matching Across Units

"Chicken breast" should match "chicken" in the fridge. "2 cups flour" and "500g flour" are the same quantity in different systems. I built a fuzzy matching engine with metric/imperial unit conversion that produces meaningful match percentages.

RevenueCat in Development

Emulators don't support billing, sandbox receipts behave differently, and webhooks can't reach localhost. I built dev-mode bypasses to simulate the premium flow while ensuring production builds use real entitlements.

Accomplishments I'm proud of

  • The full pipeline works end-to-end: Paste a TikTok URL → AI extracts the recipe → tap "Add Missing" → walk into the grocery store with a categorized list. That's Eitan's brief, fully realized.

  • It feels native, not like a hackathon project. Spring animations, haptic feedback, swipe gestures, collapsible headers, tutorial overlays — I spent significant time on micro-interactions because cooking apps live or die on how they feel in the kitchen with messy hands.

  • Offline-first actually works. Airplane mode? No problem. Your recipes, fridge, and shopping list are all local. This is critical for users in grocery stores with spotty reception.

  • The monetization model is sustainable. Free users get real value (3 video parses/month, full recipe library, fridge matching, shopping list). Premium unlocks power features (unlimited parsing, PDF cookbooks, AI search, cloud sync). It's not a paywall that blocks core functionality — it's a ladder that rewards engagement.

  • Smart fridge matching turns a passive recipe library into an active cooking assistant. Instead of asking "what should I cook?", Cuisy says "here are 5 recipes you can make right now with what you have, and here's what you're missing for 3 more."

What I learned

  • Audience-first design matters more than feature count. I could have built 20 features, but Eitan's audience needs three things done exceptionally well: capture, organize, and shop. Every other feature exists to support those three.

  • Offline-first is worth the upfront cost. It's harder to architect, but the UX payoff is enormous. No loading spinners for local data. No "connection error" screens. The app just works.

  • RevenueCat makes monetization accessible. Without it, implementing cross-platform subscriptions with receipt validation, trial management, and webhook sync would have taken weeks. With RevenueCat, it took days.

  • AI extraction is only as good as your fallback strategy. Transcripts fail, videos get blocked, AI hallucinates ingredients. Building graceful error handling and confidence scoring was as important as the AI itself.

  • Micro-interactions compound. No single animation makes the app great. But haptic feedback on every tap, spring physics on every transition, and undo toasts on every destructive action — together, they create an experience that feels crafted, not coded.

What's next for Cuisy: Recipes & Grocery List

  • Collaborative shopping lists — share a grocery list with your partner and check off items in real-time
  • Meal planning calendar — drag recipes onto a weekly calendar and auto-generate a consolidated grocery list for the entire week
  • Pantry tracking with expiration alerts — reduce food waste by surfacing recipes that use ingredients about to expire
  • Social recipe sharing — share captured recipes as beautiful cards on Instagram Stories or iMessage
  • Apple Watch companion — quick grocery list access on your wrist while shopping
  • Widget support — "Ready to Cook" home screen widget showing today's top matches

Built With

  • apache-tika-(pdf-text-extraction)
  • apple-sign-in
  • aspectj
  • aspectj-(tier-gating)-ai/ml:-openai-(chat/vision/embeddings)
  • async
  • capture-job
  • docker-/-docker-compose-auth-&-billing:-google-sign-in
  • dockercompose
  • expo-push-notifications-document-&-media-processing:-apache-tika-(pdf-text-extraction)
  • expo-router
  • expo-sdk-54
  • expo.io
  • firebase-admin-sdk
  • flashlist
  • flashlist-backend:-spring-boot-4.0.1
  • google-gemini-(video-fallback)
  • google-sign-in
  • java25
  • notifications
  • openai-(chat/vision/embeddings)
  • pgvector
  • pgvector-(vector-search)-infra/cloud:-railway-(backend-hosting)
  • postgresql-16
  • push
  • python
  • python-(transcript-utility)-frontend:-expo-sdk-54
  • rag-pipeline
  • railway-(backend-hosting)
  • react-19
  • react-native-0.81
  • react-query
  • reanimated
  • redis-cache
  • redis-service
  • revenuecat
  • revenuecat-webhook-integration-notifications:-firebase-admin-sdk
  • spring-ai
  • spring-boot-4.0.1
  • spring-data-jpa
  • spring-security-(jwt-+-oauth)
  • sql
  • sqlite-(local-first-mobile-storage)
  • structured-json-outputs-databases:-postgresql-16
  • structuredjsonoutputs
  • token-chunking
  • typescript
  • vectorsearch
  • webhook
  • zustand
Share this project:

Updates