About the Project

Inspiration

MealMode started from a practical pain point: planning meals, tracking pantry inventory, and shopping were all happening in separate places. We wanted one flow that answers three questions quickly:

  1. What should we cook this week?
  2. What do we already have?
  3. What do we still need to buy?

We also wanted importing recipes to be less manual, so we built a URL-based recipe import flow that can pre-fill ingredients and steps, then let users verify everything before saving.

What We Built

MealMode is a full-stack meal planning app with:

  • A recipe library (create, browse, filter by tags, cost, and calories)
  • A weekly planner (assign meals by day and slot)
  • Pantry/inventory tracking (on-hand quantities and ingredient management)
  • Auto-generated shopping lists (subtracting what’s already in stock)
  • Recipe URL import with a review-and-confirm workflow
  • Ingredient cost intelligence using scraped price sources + manual fallback pricing

How We Built It

  • Frontend: React + TypeScript + Vite, React Router, React Query, Tailwind CSS
  • Backend: Django + Django REST Framework + django-filter + drf-spectacular
  • Data/API workflow: OpenAPI schema generation + typed API client generation (Orval)
  • Parsing/import pipeline: requests + BeautifulSoup for JSON-LD recipe extraction
  • Ingredient matching: NLTK tokenization/POS tagging + weighted overlap scoring
  • Infra: Docker Compose with Postgres, backend service, and Caddy-served frontend

A key architectural decision was splitting recipe import into stages:

  1. Extract recipe schema from URL
  2. Attempt ingredient matching and quantity normalization
  3. Save as a confirmable draft
  4. Let user edit/resolve mismatches
  5. Confirm and persist as a real recipe (transactionally)

Challenges We Faced

  • Messy web recipe formats: Not every site has clean schema markup; JSON-LD structures vary a lot.
  • Ingredient matching ambiguity: “1 cup chopped onion” vs “onion” required normalization, token weighting, and confidence scoring.
  • Unit conversion tradeoffs: Converting cups/tbsp/pieces to base units is approximate without density-specific metadata.
  • Data consistency during import: We had to handle add/edit/delete on draft ingredients and steps before final confirmation.
  • State synchronization: Keeping planner, recipes, pantry, and shopping list in sync required careful query invalidation and optimistic UI updates.

What We Learned

  • Designing a human-in-the-loop import system is more reliable than trying to fully automate messy real-world recipe data.
  • Typed API contracts significantly reduce frontend/backend drift and speed up iteration.
  • Meal planning is not just CRUD; once costs, nutrition, pantry stock, and scheduling intersect, modeling decisions matter a lot.
  • Good UX for confirmation/review screens is essential when confidence-based automation is involved.

What’s Next

  • Better ingredient matching using embeddings/semantic search
  • More accurate unit conversions with ingredient-specific density tables
  • Smarter planning suggestions based on budget/nutrition goals
  • Real checkout integrations (instead of demo handoff flow)
  • Collaborative household planning and shared pantry support

Built With

Share this project:

Updates