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.pygenerates TS types from the spec).
How It Is Wired
- Startup –
docker/docker-compose.ymldefinesmealie-backendandmealie-frontend. The backend service runsdocker/entry.sh, which executes ``bash uvicorn mealie.main:app --host 0.0.0.0 --port 8000`(mealie/main.pyimports routes frommealie/api.py`). - API Layer –
mealie/api.pyregisters FastAPI routers (e.g.,/recipes,/mealplans). Each router imports SQLAlchemy models frommealie/models.pyand uses Pydantic schemas frommealie/schemas.py. - Frontend Calls –
frontend/app/composables/api/index.tswrapsfetchcalls to the backend. The composable is used by all domain components. - Data Flow – A recipe import triggers
POST /recipes/import, handled inmealie/api.py. The handler fetches the URL, parses content viamealie/utils/recipe_parser.py, creates aRecipemodel, and writes it to the database. - OpenAPI Generation –
dev/code-generation/main.pyreads 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.