The Problem

Families want a single place to store recipes, plan meals, and generate shopping lists without relying on commercial SaaS. Manual spreadsheets or disparate tools lack automatic recipe import, API integration, and local hosting.

What This Does

Mealie is a full stack solution: a FastAPI‑based REST backend (mealie/ folder) and a Nuxt 3 reactive frontend (frontend/).

  • Import recipes automatically from URLs or via the UI editor (frontend/app/components/Domain/Recipe/RecipeActionMenu.vue).
  • Plan weekly meals (frontend/app/components/Domain/Mealplan/MealPlanLayout.vue).
  • Create shopping lists grouped by grocery sections (frontend/app/components/Domain/Household/HouseholdPreferencesEditor.vue).
  • Group recipes into cookbooks (frontend/app/components/Domain/Cookbook/CookbookPage.vue).
  • Expose a documented OpenAPI spec for integrations (dev/code-generation/main.py generates TS types from the spec).

How It Is Wired

  1. Startup – docker/docker-compose.yml defines mealie-backend and mealie-frontend. The backend service runs docker/entry.sh, which executes ``bash uvicorn mealie.main:app --host 0.0.0.0 --port 8000 ` (mealie/main.py imports routes from mealie/api.py`).
  2. API Layer – mealie/api.py registers FastAPI routers (e.g., /recipes, /mealplans). Each router imports SQLAlchemy models from mealie/models.py and uses Pydantic schemas from mealie/schemas.py.
  3. Frontend Calls – frontend/app/composables/api/index.ts wraps fetch calls to the backend. The composable is used by all domain components.
  4. Data Flow – A recipe import triggers POST /recipes/import, handled in mealie/api.py. The handler fetches the URL, parses content via mealie/utils/recipe_parser.py, creates a Recipe model, and writes it to the database.
  5. OpenAPI Generation – dev/code-generation/main.py reads the OpenAPI spec produced by FastAPI, then writes TypeScript types (frontend/types/) and route helpers (frontend/app/composables/routes/index.ts).

The backend’s “hub” is mealie/api.py; it touches the database, the parser, and the OpenAPI spec. Any change to route definitions cascades to the frontend typings, so maintainers should edit api.py carefully.

How To Use It

# Clone
git clone https://github.com/moses-y/mealie

# Build & run containers
cd mealie
docker compose -f docker/docker-compose.dev.yml up --build

The dev Compose file mounts frontend/ and starts the Nuxt dev server on http://localhost:3000. For a production image:

docker compose -f docker/docker-compose.yml up -d

Configuration is via environment variables defined in .env.example (copy to .env). To run tests:

# Backend
pytest -q tests/

# Frontend
cd frontend
pnpm install
pnpm test

Real‑World Use

A family installs Mealie locally, imports a recipe from a cooking blog, then schedules it for Monday, Wednesday, and Friday. After a week, the shopping list is exported to a CSV and shared with the grocery app. A webhook (frontend/app/components/Domain/Group/GroupWebhookEditor.vue) posts the list to a home‑assistant instance for automatic inventory tracking.

Code Health & Issues

  • CI – GitHub Actions workflows (.github/workflows/*) run linting, unit tests, and e2e tests.
  • Tests – 296 test files cover both backend (tests/) and frontend (tests/e2e/).
  • Static analysis – No structural red flags reported.
  • Licensing – AGPL‑3.0+ (LICENSE).
  • Documentation – Extensive docs under docs/, including migration and API guides.

The Bottom Line

Mealie delivers a self‑hosted, feature‑rich recipe and meal‑planning platform with a clean separation between a FastAPI backend and a Nuxt frontend. The repository is well‑structured, CI‑enabled, and fully containerized, making it suitable for teams that need a controllable, open‑source kitchen hub.