Build Guide
How to Build a Recipe App
A recipe app with AI meal planning and automatic grocery list generation has a 15% conversion to $12/month — better than most B2B tools.
Recipe apps teach image handling, structured data (ingredients, steps, nutrition), filtering, user-generated content, and nutrition API integration — transferable to any content-heavy consumer app.
Data model
The core tables you'll need before writing any UI.
Build order
The sequence that minimises rewrites — build in this order.
Recipe card and detail page
Build a recipe card (image, title, time, difficulty, diet tags) and a detail page with ingredients list, step-by-step instructions, and serving size scaler. Hardcode 3 recipes to get the layout right.
Search and filters
Add a search input that filters by title. Add filter pills for cuisine (Italian, Asian, Mexican), diet (vegan, gluten-free, keto), and time range (under 30 min, under 1 hour). Combine filters with AND logic.
User accounts and favourites
Add Clerk auth. Add a favourite button on each recipe card — toggle a user_favorites join table. Add a /favourites page that shows saved recipes. Serve this as the logged-in homepage.
Weekly meal planner
Build a 7-day grid (Mon–Sun). Allow dragging or clicking a + button to assign a recipe to a meal slot. Save the plan per week to the meal_plan_entries table.
Grocery list generation
From the meal plan, collect all ingredient rows from all planned recipes. Group by ingredient name (merge quantities with the same unit). Generate a consolidated list sorted by aisle category. Add a check-off UI.
Serving size scaler
Multiply all ingredient quantities by (desired servings / recipe servings). Update the ingredient list in real time as the user adjusts the serving count with a +/- control. Format quantities cleanly (1.5 tsp not 1.499999 tsp).
AI recipe generation
Add a "Generate a recipe from what I have" feature. User enters ingredients (tomatoes, chicken, garlic). POST to /api/generate-recipe, call Claude with a prompt to return a full recipe as structured JSON. Parse and display it.
Done when
Observable behaviors that confirm V1 is complete — verify each one before you ship.
- ✓
Search, cuisine filter, and diet filter work simultaneously — results update without a page reload
- ✓
Serving scaler updates all ingredient quantities in real time as the user adjusts the count
- ✓
Weekly meal plan generates a consolidated grocery list with merged ingredient quantities
- ✓
AI generates a valid, structured recipe from a list of ingredients within 10 seconds
- ✓
App opens with 6 seeded recipes across 3 cuisines — filters and search work immediately
First Run Requirement
Seed 6 demo recipes (2 Italian, 2 Asian, 2 Mexican) with real ingredients and steps. Filters and search are functional on first visit — no blank state.
Build it with AI — Architect Prompt
Paste this into Claude, Cursor, Windsurf, or any AI coding tool. It includes the full context of this guide — data model, build order, done conditions, and pitfalls — so the AI starts with everything it needs.
<context>
App: Recipe App
Difficulty: Beginner
Estimated build time: 3–7 days
Tech stack (intermediate): Next.js + Supabase + Spoonacular API + Clerk — accounts with saved recipes and meal plans
Data model:
Recipe: id, user_id, title, description, servings, prep_time, cook_time, difficulty, cuisine, diet_tags[], cover_image, published
Ingredient: id, recipe_id, name, quantity, unit, preparation_note
Step: id, recipe_id, position, instruction, image_url (optional)
MealPlan: id, user_id, week_start_date
MealPlanEntry: id, meal_plan_id, recipe_id, day (0–6), meal_type (breakfast/lunch/dinner)
FIRST RUN REQUIREMENT:
Seed 6 demo recipes (2 Italian, 2 Asian, 2 Mexican) with real ingredients and steps. Filters and search are functional on first visit — no blank state.
DONE WHEN — verify each before marking V1 complete:
□ Search, cuisine filter, and diet filter work simultaneously — results update without a page reload
□ Serving scaler updates all ingredient quantities in real time as the user adjusts the count
□ Weekly meal plan generates a consolidated grocery list with merged ingredient quantities
□ AI generates a valid, structured recipe from a list of ingredients within 10 seconds
□ App opens with 6 seeded recipes across 3 cuisines — filters and search work immediately
Recommended build order:
1. Define API contract + schema + seed data (always first)
2. Recipe card and detail page — Build a recipe card (image, title, time, difficulty, diet tags) and a detail page with ingredients list, step-by-step instructions, and serving size scaler. Hardcode 3 recipes to get the layout right.
3. Search and filters — Add a search input that filters by title. Add filter pills for cuisine (Italian, Asian, Mexican), diet (vegan, gluten-free, keto), and time range (under 30 min, under 1 hour). Combine filters with AND logic.
4. User accounts and favourites — Add Clerk auth. Add a favourite button on each recipe card — toggle a user_favorites join table. Add a /favourites page that shows saved recipes. Serve this as the logged-in homepage.
5. Weekly meal planner — Build a 7-day grid (Mon–Sun). Allow dragging or clicking a + button to assign a recipe to a meal slot. Save the plan per week to the meal_plan_entries table.
6. Grocery list generation — From the meal plan, collect all ingredient rows from all planned recipes. Group by ingredient name (merge quantities with the same unit). Generate a consolidated list sorted by aisle category. Add a check-off UI.
7. Serving size scaler — Multiply all ingredient quantities by (desired servings / recipe servings). Update the ingredient list in real time as the user adjusts the serving count with a +/- control. Format quantities cleanly (1.5 tsp not 1.499999 tsp).
8. AI recipe generation — Add a "Generate a recipe from what I have" feature. User enters ingredients (tomatoes, chicken, garlic). POST to /api/generate-recipe, call Claude with a prompt to return a full recipe as structured JSON. Parse and display it.
9. End-to-end verification — walk every Done When condition above (always last)
Known pitfalls to avoid:
- Storing ingredient quantities as strings — "1 cup" and "250ml" are the same thing but string comparison won't merge them. Store quantity as a float and unit separately. Use a unit normalisation table for conversions.
- Fetching full recipes to build a search index — for fast search, store a denormalised search_text field on the recipe (title + tags + ingredients joined). Run ILIKE on that field instead of JOINing the ingredients table on every search.
- Rounding ingredient quantities badly — 1/3 cup × 3 = 0.999... cups which displays as 0.99. Use Fraction.js to handle rational arithmetic for quantities, or round to the nearest common fraction (1/4, 1/3, 1/2, 2/3, 3/4).
</context>
<role>
You are a Senior Full-Stack Engineer and product architect who has shipped production Recipe Apps before. You know exactly where developers get stuck and how to structure the project to avoid rewrites.
</role>
<task id="step-1-clarify">
Before writing any code or spec, ask me 3–5 clarifying questions that will meaningfully change the architecture. Focus on: scale expectations, auth requirements, platform (web / mobile / both), must-have vs nice-to-have features for the MVP, and any hard constraints (budget, deadline, existing infrastructure).
<example>
BAD: "What tech stack do you want to use?" — too broad, doesn't change architecture decisions.
GOOD: "Do you need real-time sync across devices, or is single-device with periodic refresh acceptable? This decides whether we use WebSockets or simple REST polling and significantly affects infrastructure complexity."
</example>
⚠️ Do NOT start planning or writing code until I answer. Present the questions, then stop and wait.
</task>
<task id="step-2-architect">
After I answer your questions, produce the following in order:
1. TECHNICAL SPECIFICATION
- System architecture using → to show data and event flow
- Core data model (refer to data model in <context>)
- API contract — list ALL routes with request/response shapes BEFORE any implementation
WHY: agreeing on contracts first prevents rewrites when frontend and backend shapes diverge
- External APIs and integration points
2. MVP PLAN in three phases:
SETUP ✦ Step 1 (always): API contract + schema migration + seed data
Done when: schema is migrated, seed script runs, app starts with demo data, zero manual setup.
CORE FEATURES — build in this exact order:
2. Recipe card and detail page
3. Search and filters
4. User accounts and favourites
5. Weekly meal planner
6. Grocery list generation
7. Serving size scaler
8. AI recipe generation
DONE WHEN — one observable condition per feature:
□ Search, cuisine filter, and diet filter work simultaneously — results update without a page reload
□ Serving scaler updates all ingredient quantities in real time as the user adjusts the count
□ Weekly meal plan generates a consolidated grocery list with merged ingredient quantities
□ AI generates a valid, structured recipe from a list of ingredients within 10 seconds
□ App opens with 6 seeded recipes across 3 cuisines — filters and search work immediately
STRETCH GOALS — post-launch additions that are explicitly out of V1 scope.
3. BLOCKER ANALYSIS
Flag: API rate limits, auth complexity, scope risks, cold-start problems, top 2–3 failure modes.
FIRST RUN REQUIREMENT: Seed 6 demo recipes (2 Italian, 2 Asian, 2 Mexican) with real ingredients and steps. Filters and search are functional on first visit — no blank state.
✓ Done when: app launches with seed data and the full user journey works without any manual setup.
<self_check>
Before presenting your output, verify:
□ Every answer I gave to clarifying questions is reflected in the spec
□ Step 1 is ALWAYS: API contract + schema + seed — never UI first
□ Done When criteria are observable user behaviors, not internal states
□ The plan is realistic for one person to ship within 3–7 days
□ All known pitfalls from <context> are addressed in the spec
</self_check>
</task>
<task id="step-2.5-agents-md">
Generate an AGENTS.md file at the project root. This file is read automatically by Claude Code, Cursor, Windsurf, and all major AI coding tools at the start of every session.
Include:
- Project overview (2–3 sentences)
- Tech stack with exact version numbers
- Folder structure with one-line descriptions per directory
- Key architectural decisions and the WHY behind each
- Coding conventions: camelCase components, kebab-case files, max 200 lines per file, one concern per file
- Available commands: dev, build, test, lint, db:migrate, db:seed
- MVP scope boundaries — features explicitly out of V1
Note in the file: "Cursor users: symlink .cursorrules → AGENTS.md. Claude Code users: symlink CLAUDE.md → AGENTS.md."
</task>
<task id="step-3-implement">
Implement the full project in the exact order from step 2. For each step:
- Write complete code (no placeholders or TODOs)
- Confirm the step works before moving to the next
<constraints>
- Step 1 is ALWAYS: define all API routes + TypeScript request/response interfaces + run schema migration
WHY: agreeing on contracts before writing a single component prevents shape mismatches that require rewrites
- Final step is ALWAYS: start the app and walk every Done When condition from <context> end-to-end
WHY: a spec that passes unit tests but breaks the core user journey is not done
- Max 200 lines per file. WHY: every file must fit in one AI context window for complete reasoning
- One concern per file. WHY: mixing auth logic into API routes makes it impossible to reuse — extract to lib/auth.ts
- TypeScript strict mode, no `any` types. WHY: catches data shape mismatches at compile time, not in production
- All database queries in server components or API routes only. WHY: keeps credentials server-side
- All environment variables documented in .env.example. WHY: next developer sets up in under 5 minutes
</constraints>
</task>How to use this prompt
- 1.Copy the prompt above
- 2.Open Claude, Cursor (Cmd+L), or Windsurf
- 3.Paste the prompt and send — the AI will ask 3–5 clarifying questions
- 4.Answer the questions, then it generates your full project spec
- 5.Continue in the same session to implement step by step
Common mistakes
What trips up most developers building this for the first time.
Storing ingredient quantities as strings — "1 cup" and "250ml" are the same thing but string comparison won't merge them. Store quantity as a float and unit separately. Use a unit normalisation table for conversions.
Fetching full recipes to build a search index — for fast search, store a denormalised search_text field on the recipe (title + tags + ingredients joined). Run ILIKE on that field instead of JOINing the ingredients table on every search.
Rounding ingredient quantities badly — 1/3 cup × 3 = 0.999... cups which displays as 0.99. Use Fraction.js to handle rational arithmetic for quantities, or round to the nearest common fraction (1/4, 1/3, 1/2, 2/3, 3/4).
Recommended tech stack
Pick the level that matches your experience.
React + Spoonacular API (free tier) — 5,000+ searchable recipes, no backend needed
Next.js + Supabase + Spoonacular API + Clerk — accounts with saved recipes and meal plans
Next.js + Supabase + Claude API (AI recipe generation) + Nutritionix API + Stripe ($12/month Pro)
Take it further — related ideas
Each comes with revenue math, a full build guide, and a prompt to paste into Claude or Cursor.