Feature spec
IntermediateCategory
vertical-tools
Build with AI
3-6 hours with Lovable or V0
Custom build
1-2 weeks custom dev (including nutrition API integration)
Running cost
$0/mo early stage · $75-150/mo at 10K users
Works on
Everything it takes to ship a Recipe Calorie Calculator — parts, prompts, and real costs.
A recipe calorie calculator needs three things: an ingredient search wired to a nutrition API (Nutritionix or the free USDA FoodData Central), client-side math converting quantities to macros, and a save mechanism for users to store their recipes. With V0 or Lovable you can ship a working calculator in 3–6 hours. The USDA API is free for early builds; running costs only appear at scale when API call volume or recipe storage exceeds free tiers.
What a Recipe Calorie Calculator Actually Is
A recipe calorie calculator lets users build a recipe by searching for ingredients, entering quantities, and seeing real-time macro totals update as they type. The three numbers that matter — calories, protein, fat, carbs — are calculated client-side from nutrition data fetched per ingredient. The product decisions behind this feature are which nutrition database to use (USDA is free and accurate; Nutritionix has a better search UX), how to handle unit conversions (the most common source of wildly wrong totals), and whether recipes are saved to an account or just calculated ephemerally. A servings adjuster that scales all values proportionally and a visual macro donut chart are the two elements users expect in 2026 — apps without them look half-built.
What users consider table stakes in 2026
- Ingredient search with autocomplete that returns results as the user types, debounced so it doesn't fire on every keystroke
- Per-ingredient quantity input with unit selection (g, oz, cup, tbsp) that converts to grams before running the calculation
- Running calorie and macro totals (calories, protein, fat, carbs) that update in real time as ingredients are added or quantities are changed
- Servings stepper (1–20+) that scales all total values proportionally when adjusted
- Visual macro breakdown chart — donut or bar — showing the percentage split between protein, fat, and carbs
- Save and share button that persists the recipe to the user's account and generates a shareable URL
- Mobile-friendly ingredient entry with large tap targets and a numeric keyboard for quantity fields
Anatomy of the Feature
Seven components. The client-side macro math and the debounced search input are where first builds go wrong. Everything else — the form, the chart, the DB — AI tools handle reliably.
Ingredient search input
UIA combobox with debounced search that queries the nutrition API as the user types. Built with shadcn/ui Command (web) or react-select. Debounce of 300ms prevents rate limit exhaustion on Nutritionix free tier. Each result shows the food name and serving size; selecting it adds a row to the ingredient list.
Note: USDA FoodData Central returns many duplicates across data sources. Filter results to Foundation Foods and SR Legacy types using the dataType query parameter to reduce noise.
Nutrition API client
ServiceFetches calories, protein, fat, and carbs per 100g for a given food. Primary option: Nutritionix Track API (nutritionis.com) — better search UX, 500 free calls/day. Free alternative: USDA FoodData Central REST API — completely free at 3,600 calls/hour per API key, government-maintained data. Both return values per 100g, which the calculator logic then adjusts to the entered quantity.
Note: Call the nutrition API from a server-side route (Next.js API route or Supabase Edge Function) to keep the API key out of the browser. Cache results in Supabase to avoid hitting rate limits.
Ingredient list with quantity inputs
UIA react-hook-form field array (useFieldArray) where each row has the ingredient name, a quantity number input, and a unit selector using shadcn/ui Select. On every onChange event the macro calculator function is called and totals update. Rows are removable with a delete icon.
Note: Use register('quantity', { valueAsNumber: true }) in react-hook-form to avoid string/number type mismatches in the calculation — a common source of NaN totals.
Macro calculator logic
DataPure client-side JavaScript: for each ingredient, convert the entered quantity to grams using a unit conversion table (1 cup = 240ml ≈ 240g for liquids, 1 oz = 28.35g, 1 tbsp = 15g). Then apply (quantity_in_grams / 100) * per_100g_value for each macro. Sum across all ingredients. Divide each total by the servings count to get per-serving values.
Note: The single most common AI mistake: forgetting to divide by 100. The API returns values per 100g, not per gram. Always verify the formula: (quantity_in_grams / 100) * api_per_100g.
Macro visualization
UIRecharts PieChart (web) or fl_chart PieChartSectionData (Flutter) showing the calorie percentage breakdown: protein (4 kcal/g), fat (9 kcal/g), carbs (4 kcal/g). shadcn/ui Progress bars per macro for a simpler alternative. Recharts ResponsiveContainer wraps the chart so it scales to any screen width.
Note: Wrap Recharts PieChart in a conditional that only renders when the ingredient list is non-empty — an empty data array causes a rendering error.
Recipe persistence
BackendSupabase table recipes stores the full ingredient list as JSONB alongside the calculated macro totals. user_id references auth.users. RLS policy restricts read and write to the owning user. A saved recipe can be reloaded, edited, and recalculated. Optional: a is_public flag lets users share recipes via a public URL without login.
Note: Store per_serving_kcal separately from total_kcal — a common save bug stores the un-divided total and the per-serving display is wrong on reload.
Flutter nutrition tile (mobile)
UIOn the mobile path: Flutter ListView.builder renders one ListTile per ingredient with a TextFormField for quantity input and a DropdownButton for unit. fl_chart PieChartSectionData renders the macro ring. All calculation logic runs in Dart using the same per-100g formula as the web version.
Note: Use FocusNode to manage keyboard dismissal after quantity entry — without it the keyboard stays open and obscures the running totals.
The data model
Two tables: one for saved recipes (with calculated totals stored for fast reload) and an optional cache table that prevents re-hitting the nutrition API for foods users have looked up before. Run this in the Supabase SQL editor.
1create table public.recipes (2 id uuid primary key default gen_random_uuid(),3 user_id uuid references auth.users(id) on delete cascade not null,4 name text not null,5 servings int not null default 1,6 ingredients jsonb not null default '[]',7 total_kcal decimal(10,2),8 total_protein decimal(10,2),9 total_fat decimal(10,2),10 total_carbs decimal(10,2),11 per_serving_kcal decimal(10,2),12 is_public bool not null default false,13 created_at timestamptz not null default now(),14 updated_at timestamptz not null default now()15);1617-- Optional: cache nutrition API responses to reduce calls18create table public.saved_foods (19 id uuid primary key default gen_random_uuid(),20 food_api_id text not null unique,21 food_name text not null,22 source text not null default 'usda',23 per_100g_kcal decimal(10,2),24 per_100g_protein decimal(10,2),25 per_100g_fat decimal(10,2),26 per_100g_carbs decimal(10,2),27 cached_at timestamptz not null default now()28);2930-- Enable RLS31alter table public.recipes enable row level security;32alter table public.saved_foods enable row level security;3334-- Users can only access their own recipes, or public recipes35create policy "Users can view own or public recipes"36 on public.recipes for select37 using (auth.uid() = user_id or is_public = true);3839create policy "Users can insert own recipes"40 on public.recipes for insert41 with check (auth.uid() = user_id);4243create policy "Users can update own recipes"44 on public.recipes for update45 using (auth.uid() = user_id);4647create policy "Users can delete own recipes"48 on public.recipes for delete49 using (auth.uid() = user_id);5051-- saved_foods cache is readable by all authenticated users52create policy "Authenticated users can read food cache"53 on public.saved_foods for select54 using (auth.role() = 'authenticated');5556create policy "Authenticated users can insert food cache"57 on public.saved_foods for insert58 with check (auth.role() = 'authenticated');5960-- Index for user recipe lists61create index recipes_user_created_idx on public.recipes (user_id, created_at desc);62create index saved_foods_api_id_idx on public.saved_foods (food_api_id);Heads up: The saved_foods cache table is the key to staying within the Nutritionix free tier at scale — once a food is looked up by any user, the result is served from your database on subsequent requests. The per_serving_kcal column stores total_kcal / servings at save time so reload shows correct per-serving values without recalculating.
Build it — pick your path
Each tool fits this feature differently. Switch tabs to compare fit, time, the exact steps, and a copy-paste prompt.
The strongest choice for this feature — V0 generates polished Recharts macro visualizations and the shadcn/ui Combobox ingredient search naturally. The Next.js API route keeps the nutrition API key server-side, and Vercel Edge Cache reduces API calls automatically.
Step by step
- 1Prompt V0 with the spec below to generate the calculator component and the /api/nutrition API route
- 2In the V0 Vars panel, add USDA_API_KEY (free from api.nal.usda.gov) and NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY
- 3Run the SQL schema from this page in the Supabase SQL editor
- 4Deploy to Vercel — the Next.js API route automatically becomes a serverless function with the env vars injected
- 5Verify on mobile that the servings stepper updates all values simultaneously and that the macro chart re-renders correctly
Build a recipe calorie calculator in Next.js App Router with shadcn/ui and Recharts. API route at /api/nutrition: accepts a 'query' search param, calls USDA FoodData Central API (api.nal.usda.gov/fdc/v1/foods/search) with the USDA_API_KEY env var server-side, filters results to dataType=Foundation,SR%20Legacy, returns simplified array of {foodId, name, kcal, protein, fat, carbs} per 100g. Add Cache-Control: s-maxage=3600 to cache identical searches for one hour. Client page at /calculator: shadcn/ui Command combobox that calls /api/nutrition with 300ms debounce, shows 'No results' state and 'API error — try again' state. Below: react-hook-form useFieldArray, each row has ingredient name, quantity number input (valueAsNumber, min 0.1), unit Select (g, oz, cup, tbsp, tsp, ml) with conversion constants (oz: 28.35, cup: 240, tbsp: 15, tsp: 5, ml: 1). Compute (quantity_in_grams / 100) * per_100g for each macro on every change. Running totals row. Servings number input (1–20) that divides totals; updates all four values simultaneously. Recharts ResponsiveContainer PieChart showing macro calorie split — guard with data.length > 0 check. Supabase save button: persists name, servings, ingredients array, total_kcal, total_protein, total_fat, total_carbs, per_serving_kcal to the recipes table — require auth, show 'Sign in to save' message for unauthenticated users. Empty state: centered message 'Search for an ingredient above to start building your recipe'.Where this path bites
- V0 does not auto-provision Supabase — the recipes table must be created manually using the SQL schema from this page
- Environment variables for the nutrition API key and Supabase must be added in the Vercel Dashboard after deployment — V0 Vars panel is for local preview only
- Recharts is not in the shadcn registry — V0 may generate an incorrect import path; prompt 'fix the Recharts import to use recharts directly' if the chart component fails
Third-party services you'll need
The USDA FoodData Central API is completely free and adequate for most early-stage builds. Nutritionix adds better search UX but introduces a paid tier at volume. Supabase covers storage and auth.
| Service | What it does | Free tier | Paid from |
|---|---|---|---|
| USDA FoodData Central API | Free government nutrition database — calories, protein, fat, carbs per 100g; 3,600 calls/hour per API key | Free, no paid tier (government-funded) | Free |
| Nutritionix Track API | Ingredient nutrition lookup with better natural language search than USDA | 500 calls/day | From $50/mo for higher limits (approx) |
| Open Food Facts API | Free, open-source food database — good for packaged food barcodes; coverage varies by country | Free, no rate limit documented | Free |
| Supabase | Recipe storage (recipes + saved_foods tables), user auth for saved recipes | Free tier sufficient for early stage builds | $25/mo (Pro) |
Swipe the table sideways to see pricing.
What it costs to run
Drag through the tiers to see how your monthly bill scales with users — no surprises later.
Estimated monthly running cost
USDA API is free. Supabase free tier covers recipe storage and auth. No external cost at this scale.
Estimates use verified 2026 pricing and assume typical usage per user. Your real bill depends on activity, storage, and third-party plans.
What breaks when AI tools build this
The failures people actually hit on their first build — the symptom, why it happens, and the exact fix.
Calorie totals are 100x too high (or wildly off in other directions)
Symptom: The USDA and Nutritionix APIs return macro values per 100g, not per gram. If the AI generates the calculation as quantity_in_grams * per_100g_value without dividing by 100, a 50g portion of chicken shows ~1,500 calories instead of ~85. This is the single most common bug in AI-built calorie calculators and it happens because the variable name 'per_100g_protein' looks like a unit when it is actually a rate.
Fix: Always verify the generated calculation function: the correct formula is (quantity_in_grams / 100) * per_100g_value. Add a sanity check assertion in the function: if total_kcal for a single ingredient exceeds 900 kcal/100g, something is wrong. Butter is the highest common food at ~717 kcal/100g.
Ingredient search exhausts the free API limit within minutes during testing
Symptom: Without debounce on the search input, every keystroke fires an API request. Typing 'chicken breast' (13 characters) sends 13 requests. During a testing session with multiple developers, the Nutritionix 500 calls/day free limit can be exhausted in under 30 minutes. Lovable and V0 frequently omit debounce on the first build.
Fix: In the generated search handler, wrap the API call in a setTimeout of 300ms and cancel the previous timer on each keystroke using a ref: const timerRef = useRef(); clearTimeout(timerRef.current); timerRef.current = setTimeout(() => fetchNutrition(query), 300). Add the saved_foods cache table so repeated lookups for common ingredients serve from Supabase instead of the API.
Servings adjuster changes the display but saved recipe stores un-adjusted values
Symptom: When the save function is called, AI-generated code often captures total_kcal from the ingredient sum before the servings divisor is applied. The stored total is the whole-recipe value, not the per-serving value. When the recipe is reloaded, per-serving macros display incorrectly because the saved servings count no longer matches the stored totals.
Fix: In the save function, explicitly compute and store both total_kcal (the full recipe sum) and per_serving_kcal (total_kcal / servings). Store the servings count separately. On reload, display per_serving_kcal and multiply by servings to show total — never re-derive per-serving from stored totals alone.
USDA API returns multiple items with identical names, confusing users
Symptom: FoodData Central aggregates multiple data source types (SR Legacy, Foundation, Survey FNDDS, Branded) and the same food appears many times under slightly different names. A search for 'egg' returns dozens of results like 'Egg, whole, raw, fresh' appearing multiple times with minutely different nutrient values. Users cannot tell which one to pick.
Fix: Filter API results to the Foundation and SR Legacy source types using the dataType query parameter: ?query=egg&dataType=Foundation,SR%20Legacy&pageSize=15. These two sources have the most accurate nutrient data and far fewer duplicates. Display the data source name in the search result dropdown so users can see which database entry they are selecting.
Best practices
Always call the nutrition API from a server-side route (Next.js API route or Supabase Edge Function) — never from the React component directly, as API keys in the browser are visible in the Network tab
Cache nutrition API responses in a saved_foods Supabase table — common ingredients like 'chicken breast' should never hit the paid API twice across your entire user base
Store both total_kcal and per_serving_kcal at save time so recipe reload shows correct values without recalculating from the ingredient array
Debounce the ingredient search input at 300ms to stay within free API tier limits during development and low-traffic production
Show a running calorie total that updates on every quantity keystroke — users need immediate feedback, not just a total after they finish editing
Normalize all quantity units to grams before any calculation — build a unit conversion constant table (oz: 28.35, cup: 240, tbsp: 15, tsp: 5) and apply it consistently
Filter USDA API results to Foundation and SR Legacy data types to reduce duplicate entries in search results
Guard Recharts PieChart and BarChart renders with a data.length > 0 check — an empty data array causes a rendering error that crashes the entire calculator component
When You Need Custom Development
V0 and Lovable handle single-user recipe calculators with standard nutrition APIs well. These requirements push beyond a prompt-built implementation:
- App needs to sync calorie data with Apple Health (HealthKit) or Google Health Connect — requires a native app wrapper; a pure web app cannot write to either health platform
- Requires a proprietary nutrition database with brand-name packaged foods and barcode scanning for product-level calorie lookup rather than generic ingredient search
- Multi-user scenario where a nutritionist or dietitian sets custom macro targets for each client and reviews their saved recipes through a separate practitioner dashboard
- Needs offline-first support so users can log meals without an internet connection — requires service workers, IndexedDB for local storage, and a sync queue for Supabase writes when connectivity returns
RapidDev builds these features for production
Real auth, database, and payments — fixed price, delivered in weeks. You own 100% of the code.
Frequently asked questions
Which nutrition database is most accurate for recipe calculation?
USDA FoodData Central (Foundation Foods and SR Legacy sources) is the scientific gold standard — it's compiled from laboratory analysis and is government-maintained. Nutritionix draws from both the USDA database and branded product data, making it more useful for packaged foods. For home cooking recipes using generic ingredients (chicken, flour, butter), USDA is the right choice and it's completely free. For apps where users log packaged foods with specific brands, Nutritionix or Open Food Facts has better coverage.
How do I handle ingredients that aren't in the nutrition database?
Show a 'not found' state in the search results with a 'Add manually' option. Let users enter name, quantity, and manually type in calories, protein, fat, and carbs for that ingredient. Store manual entries in the saved_foods table with a source='manual' flag so they never hit the API. For apps targeting specialized cuisines, seeding a small custom ingredient table for regional foods that aren't in USDA is a common approach.
Can I scan a barcode to add packaged ingredients?
Yes — this is a natural companion feature. Use Open Food Facts API (free, no key required) to look up a barcode EAN and return the product's per-100g nutrition data. On web, html5-qrcode handles camera-based barcode scanning. On mobile, mobile_scanner (Flutter) or the device camera works natively. The scanned EAN maps to a product entry in Open Food Facts; if found, it's added to the ingredient list automatically. If not found, fall back to the manual entry flow.
What's the difference between net carbs and total carbs for keto tracking?
Net carbs = total carbs minus dietary fiber. The USDA API returns both total_carbohydrate and dietary_fiber fields. Net carbs = total_carbohydrate - dietary_fiber. To support keto mode, add a toggle in the UI that switches between total and net carbs display, and store both values when saving recipes. The macro donut chart should update to use net carbs when keto mode is active, since the calorie math stays the same (fiber contributes negligible calories in practice).
Can users set custom daily calorie targets and track against them?
That is a step beyond the recipe calculator into a daily food diary / diet planner. You'd need a daily_logs table tracking what the user ate each day, a calorie_targets table per user, and a dashboard comparing logged vs target. The recipe calculator can feed into this by letting users 'log' a recipe to their daily diary. Building the tracking layer adds about 4–6 additional hours with Lovable or V0.
Is the USDA FoodData Central API free to use in commercial apps?
Yes, unconditionally free. The USDA FoodData Central API is a government service with no licensing fee, no per-call charge, and no requirement to attribute the data source in your UI (though attribution is a good practice). The only constraint is a rate limit of 3,600 calls per hour per API key, which is generous for most apps when combined with a result caching layer.
How do I handle recipes with sub-recipes — for example a sauce used inside a larger dish?
Store each sub-recipe as its own recipe row with its own total macros. In the parent recipe's ingredient list, add a row type='recipe' alongside the standard rows. When calculating totals for the parent, fetch the child recipe's per-100g macro values (total macros / total_weight_in_grams * 100) and apply the standard formula. This requires the user to first save the sub-recipe before referencing it in the parent — a small workflow overhead that is worth documenting in your app's onboarding.
How do I add per-serving vs whole-recipe toggle?
Store both total_kcal and per_serving_kcal in the saved recipe. In the UI, add a toggle button ('Per Serving / Total Recipe') that switches which values are displayed. All four macros scale together: when showing per-serving, display value / servings; when showing total, display the full sum. The servings stepper controls the divisor. Make this toggle prominent — it's one of the first things users check when they've entered a recipe for 4 people and only want to track one portion.
Need this feature production-ready?
RapidDev builds a recipe calorie calculator into real apps — auth, database, payments — at $13K–$25K.
Book a free consultation30-min call. No commitment.