Original Idea
Recipe Scaler & Substitution Engine A web app where you paste any recipe URL, adjust servings with one click, and get smart ingredient substitutions based on dietary needs or what you have on hand.
Product Requirements Document (PRD): RecipeMorph
Version: 1.0
Status: Draft
Author: Senior Product Manager
Date: May 22, 2024 (Projected for 2026 Stack)
1. Executive Summary
RecipeMorph is a high-performance web application designed to bridge the gap between static online recipes and the dynamic needs of modern kitchens. By leveraging agentic web scraping, AI-driven semantic parsing, and rational math engines, RecipeMorph allows users to instantly import any recipe via URL, scale serving sizes without rounding errors, and intelligently swap ingredients based on dietary restrictions (Vegan, GF, Keto) or pantry availability.
2. Problem Statement
Home cooks face three primary "friction points" when using online recipes:
- Scaling Errors: Manual math for changing servings leads to ruined meals, especially in baking.
- Inflexibility: Recipes are written for "general" audiences, ignoring specific dietary needs or missing pantry items.
- Information Overload: Food blogs are cluttered with ads and narrative text, making the actual instructions hard to extract and print.
3. Goals & Success Metrics
- Parsing Accuracy: >95% success rate in converting unstructured URL content into structured JSON.
- User Retention: 30% of users save at least 3 "morphed" recipes within their first month.
- Performance: <200ms for UI updates when scaling ingredients (Optimistic UI).
- Cost Efficiency: Reduce LLM API costs by 80% through Redis semantic caching.
4. User Personas
- The Busy Parent (Alex): Needs to scale a 4-person meal to 6 quickly and swap heavy cream for a dairy-free alternative for a lactose-intolerant child.
- The Precision Baker (Sam): Requires exact fractional math (e.g., 1 3/4 cups) to be scaled down to a single serving without floating-point errors.
- The Pantry Improviser (Jordan): Has chicken and onions but is missing celery; needs a functional substitution that won't ruin the flavor profile.
5. User Stories
- As a cook, I want to paste a URL so that I can see a clean, ad-free version of the recipe.
- As a host, I want to click a "6 servings" button so that all ingredient quantities update instantly.
- As a vegan, I want to click "Butter" and see a list of animal-free alternatives with the correct 1:1 or 2:1 ratios.
- As a meal prepper, I want to print a physical copy of my modified recipe that fits on a single page.
6. Functional Requirements
6.1. URL Scraping & Parsing
- Agentic Extraction: Use Playwright-based microservices to bypass anti-bot measures and extract recipe schema.
- AI Structuring: GPT-4o must map raw text into
Ingredient,Instruction, andMetadataentities. - Canonical Normalization: Ingredients must be mapped to a standard ID (e.g., "Organic Fuji Apple" -> "apple").
6.2. Dynamic Scaling Engine
- Rational Math: All calculations must use
FractionabilityorFraction.jsto avoid0.3333errors. - Mixed Number Formatting: Display results as "1 1/2 cups" rather than "1.5 cups" for culinary readability.
- Unit Conversion: Toggle between Metric (grams/ml) and Imperial (oz/cups).
6.3. Smart Substitution Engine
- Constraint-Based Swaps: Filter substitutions by dietary tags (Vegan, GF, Keto, Paleo).
- Functional Logic: Logic must distinguish between "Butter for frying" (swap: Oil) and "Butter for baking" (swap: Applesauce).
- Ratio Application: Automatically adjust the quantity of the substitute based on AI-suggested ratios.
6.4. Print & Export
- Print-Optimized View: Automated removal of UI elements (buttons, nav) using
print:variants. - Clarity Markers: Clearly highlight substituted ingredients with a side-border to prevent kitchen mistakes.
7. Technical Requirements
7.1. Stack Specifications (2026 Standards)
- Frontend: Next.js v16.1.3 (App Router, Turbopack, Partial Prerendering).
- Styling: Tailwind CSS v4.1.x (Oxide engine, CSS-native configuration).
- Backend: FastAPI (Python 3.12+) for scraping; Node.js for the main application logic.
- Database: PostgreSQL 16+ (using
LTREEextension for ingredient taxonomy). - Caching: Redis with
RedisVLfor semantic similarity caching of LLM responses. - Math:
Fractionabilitylibrary for BigInt-based rational math. - Scraping: Playwright with
camoufoxfor TLS fingerprinting bypass. - Auth: Supabase Auth (50k MAU Free Tier).
7.2. Integrations
- OpenAI GPT-4o API: Using "Structured Outputs" with Pydantic schemas.
- Spoonacular API: For supplemental nutritional data enrichment.
- Residential Proxy Provider: For Playwright to ensure high scraping uptime.
8. Data Model
8.1. Ingredient (Taxonomy)
id: UUIDname: String (Canonical Name)path: LTREE (e.g., 'Food.Dairy.Cheese.Cheddar')is_allergen: Boolean
8.2. Recipe
id: UUIDsource_url: Stringraw_html_cache_key: String (Redis)base_servings: Integeringredients: JSONB (Array of quantity, unit, and ingredient_id)
8.3. SubstitutionMap
original_id: UUID (FK)substitute_id: UUID (FK)ratio: Numericcontext: Enum ('baking', 'high-heat', 'raw')
9. API Specification
POST /api/v1/parse
- Input:
{ "url": "https://..." } - Logic: Checks Redis for exact URL hash -> If missing, triggers Playwright scraper -> GPT-4o structures content.
- Output: Structured Recipe JSON.
GET /api/v1/substitutions/{ingredient_id}
- Query Params:
diet=vegan,context=baking - Output: List of alternative ingredients with scaling ratios.
10. UI/UX Requirements
- Server Component Default: Only the toggle buttons and substitution dropdowns should be Client Components.
- Optimistic UI: When the user changes serving size, the
useOptimistichook updates ingredient numbers instantly while the server-action persists the preference. - Accessible Fractions: Use
toMathML()from the math library to ensure screen readers read "1/2" as "one half" instead of "one slash two."
11. Non-Functional Requirements
- Security: Sanitize all scraped HTML via
DOMPurifyto prevent XSS. - Accessibility: WCAG 2.1 AA compliance; focus on high-contrast print layouts.
- Reliability: Exponential backoff for scraping services; circuit breakers for OpenAI API calls.
12. Out of Scope
- User-generated recipe uploads (MVP focuses on URL scraping only).
- Social networking features (comments, following other cooks).
- Direct grocery cart integration (Phase 2).
13. Risks & Mitigations
- Risk: Recipe sites blocking scrapers.
- Mitigation: Use a persistent browser pool in Playwright with residential proxies and human-like jitter.
- Risk: AI "hallucinating" dangerous substitutions (e.g., toxic lookalikes).
- Mitigation: Use a curated "Safety Map" in Postgres that overrides AI suggestions for high-risk ingredients.
- Risk: High LLM costs.
- Mitigation: Implement Redis semantic caching to reuse responses for similar recipes.
14. Implementation Tasks
Phase 1: Project Setup & Infrastructure
- [ ] Initialize Next.js 16.1.3 project with Turbopack and Tailwind 4.1
- [ ] Setup Supabase project and link PostgreSQL with
LTREEextension - [ ] Deploy FastAPI scraping microservice on AWS Lambda/Fargate
- [ ] Configure Redis instance with RedisBloom and RedisVL
Phase 2: Scraping & AI Parsing
- [ ] Implement Playwright scraper with
camoufoxTLS impersonation - [ ] Create Pydantic schemas for GPT-4o Structured Outputs
- [ ] Build the
/api/v1/parseendpoint with exact-match Redis caching - [ ] Develop fallback logic for when scrapers are blocked (Headful mode)
Phase 3: Core Logic (Math & Swaps)
- [ ] Integrate
Fractionabilityfor all quantity calculations - [ ] Build the Postgres
SubstitutionMapwith initial seed data (50 common swaps) - [ ] Implement the scaling logic using the "Scaling to Integer/Grams" method
- [ ] Create the substitution recommendation engine with context-awareness
Phase 4: UI & Optimistic Experience
- [ ] Build the Recipe View page using Next.js Partial Prerendering (PPR)
- [ ] Implement
useOptimisticfor the serving size toggle (1x, 2x, 4x) - [ ] Develop the substitution selection modal with "Reasoning" field
- [ ] Create the
@media printstylesheet for clean recipe exports
Phase 5: Optimization & Polish
- [ ] Add
break-inside: avoidto ingredients/instructions for print layouts - [ ] Implement semantic caching to catch similar recipe requests
- [ ] Add MathML support for ingredient accessibility
- [ ] Finalize "Pantry Check" feature to highlight missing items in red