# Project pack: Mealie @ 581ac02

Facts about **Mealie** for an AI following the [BespokeAI handover guide](https://handoff.bespokeai.software/guide/v1.md). This pack is pinned to one version and never changes after publication.

> Mealie keeps all your recipes in one place. Paste a link from any cooking site and it imports the recipe for you. Plan the week's meals on a calendar and turn them into a shopping list the whole household can share. It runs on your own computer or server, so your family's recipes stay yours.

## Version and source
- Repository: https://github.com/mealie-recipes/mealie
- Pinned commit: `581ac022b01539ac534775f65d79b72d11c045ea`. Use exactly this version.
- Get it: `git clone https://github.com/mealie-recipes/mealie mealie && cd mealie && git checkout 581ac022b01539ac534775f65d79b72d11c045ea`
- Or download a zip: https://github.com/mealie-recipes/mealie/archive/581ac022b01539ac534775f65d79b72d11c045ea.zip
- Official docs: https://docs.mealie.io
- Live demo: https://demo.mealie.io. Public demo. Don't enter anything private.
- Licence: **AGPL-3.0-only**. Free to use and change. If you run a changed version that other people use over the internet (not just your own household), you must offer them your source code under the same licence. Private family use has no extra obligations.

## Running it
- Easiest: docker run -d --name mealie -p 9925:9000 -e TZ=Europe/London -e ALLOW_SIGNUP=false -v mealie-data:/app/data ghcr.io/mealie-recipes/mealie:latest # then open http://localhost:9925 (first-time login is shown in the docs)
- Needs: Docker, or for development Python 3.14 + uv + Node 22 + pnpm + Task (taskfile.dev)
- Develop: `task setup && task py   # backend on :9000; in another terminal: task ui (frontend on :3000)`
- Test: `task py:test && task ui:test`
- Check/lint: `task py:check && task ui:check`
- Stack: python, typescript, vue (FastAPI, SQLAlchemy, Nuxt 4, Vue 3, Vuetify). Difficulty for a non-developer with an AI: **moderate**. Theme colours, AI, notifications and webhooks are pure settings. Code changes need both the Python backend and the Nuxt frontend, with type generation between them (task dev:generate).

## The project's own AI instructions
Read these in the repository before changing code: `AGENTS.md`.

## Customisation points (settings → extend → code)
- **theme-colours** [settings]: Brand colours for light and dark mode without code changes. → `THEME_LIGHT_* / THEME_DARK_* environment variables (frontend/nuxt.config.ts)`
- **households-and-language** [settings]: Who shares recipes, meal plans and shopping lists; interface language. → `Group/household settings, user profile (35+ languages)`
- **ai-provider-and-prompts** [settings]: Choose OpenAI or a local model and customise the AI prompts, e.g. "always convert to metric". → `Group settings → AI providers; custom prompts (docs/…/ai-providers.md)`
- **notifiers-and-webhooks** [extend]: Send meal-plan or shopping-list events to Telegram, Discord, Home Assistant, ntfy and more. → `Household → Notifiers / Webhooks (pages/household/notifiers.vue, webhooks.vue)`
- **api** [extend]: Scripts, smart-speaker skills, printing the week's menu, syncing with other apps. → `REST API at /docs on your instance; API tokens in user profile`
- **ui-pages** [code]: New views (e.g. a kitchen-tablet mode or kids' menu). → `frontend/app/pages/**, frontend/app/components/Domain/**`
- **backend** [code]: New data or behaviour. Run task dev:generate after schema changes. → `mealie/routes/ (controllers), mealie/services/ (logic), mealie/repos/ (data), mealie/db/models + alembic migrations`

## Must keep working
- Existing recipes, images, meal plans and shopping lists. Make a backup before changing code.
- Group and household permissions (one household must not see another's private data).
- Never edit generated types in frontend/app/lib/api/types/; regenerate with task dev:generate.
- Database changes need an Alembic migration.

## Staying updatable
Mealie's settings (theme variables, AI prompts, notifiers, webhooks, API) cover most personalisation without a fork. Reserve code changes for new screens and follow AGENTS.md.

## Data, costs and safety
- Personal data: **yes**. Stored in: SQLite in the mealie-data volume (/app/data) by default; PostgreSQL optional. Back up the data volume. Use Mealie's built-in backups (Admin → Backups) before upgrades or code changes.
- Service: OpenAI-compatible AI provider (OpenAI, Azure, Ollama…) (optional, pay-per-use (or free with local Ollama)): Import recipes from photos, videos or messy text; smarter ingredient parsing.
- Service: Email (SMTP) (optional, free with most providers): Invitations and password resets.
- Setting `TZ`: Your time zone.
- Setting `BASE_URL`: The address you'll open Mealie at (needed for links in emails and shares).
- Setting `ALLOW_SIGNUP`: Keep 'false' unless strangers should be able to create accounts.
- Setting `THEME_LIGHT_PRIMARY`: Main colour in light mode (hex). Similar THEME_LIGHT_* and THEME_DARK_* variables exist for accent, secondary and more.
- Keep ALLOW_SIGNUP=false on internet-facing instances.
- AI features send recipe text and images to the chosen provider. Use Ollama for fully local processing.

---

# Customising Mealie

Mealie is large (Python backend + Nuxt frontend), but **most family adaptations are settings**. Exhaust levels 1 and 2 before touching code.

## Level 1: Settings (no code)
- **Brand colours:** set environment variables on the container and restart it. No rebuild needed:
  `THEME_LIGHT_PRIMARY`, `THEME_LIGHT_ACCENT`, `THEME_LIGHT_SECONDARY`, `THEME_DARK_PRIMARY`, … (defaults in `frontend/nuxt.config.ts`).
- **Diets and preferences:** tags, categories, tools and *meal-plan rules* (household settings) steer what the planner suggests.
- **Shopping list order:** labels plus the shopping-list label order (food → label, then order labels by aisle).
- **AI:** group settings → AI providers. Pick OpenAI or a local Ollama, and add **custom prompts**, e.g. "always use metric units and UK ingredient names".
- **Households, members, language:** group/household settings and user profile.

## Level 2: Extend (no fork)
- **Notifiers** (Household → Notifiers): Apprise URLs for Telegram, Discord, ntfy, email, Home Assistant and more, triggered by events such as a new meal plan or a shopping-list change.
- **Webhooks** (Household → Webhooks): a scheduled POST of the day's meal plan to any URL (n8n, Home Assistant, a script).
- **REST API** (`/docs` on your instance) with a user API token: build a weekly menu printout, a voice-assistant skill, or a sync with another app.

## Level 3: Code
Read upstream `AGENTS.md` first. It's thorough. Summary:

| Change | Where |
|---|---|
| New page or view | `frontend/app/pages/**`, using components from `frontend/app/components/` (naming conventions in AGENTS.md) |
| API client in the frontend | `frontend/app/lib/api/` (types are **generated**: never edit `lib/api/types/`) |
| New endpoint | `mealie/routes/**/controller_*.py` → service in `mealie/services/` → repo in `mealie/repos/` |
| New data | `mealie/db/models/` + `task py:migrate -- "description"` + `task dev:generate` |
| Text | `frontend/app/lang/messages/en-US.json` |

## Running locally
- **Just use it:** `docker run -d -p 9925:9000 -v mealie-data:/app/data ghcr.io/mealie-recipes/mealie:latest`, then open http://localhost:9925.
- **Develop:**
  1. Install Task (taskfile.dev).
  2. Run `task setup`.
  3. Start the backend with `task py`.
  4. Start the frontend with `task ui`.
  5. Open http://localhost:3000.
- **Check:** `task py:check`, `task ui:check`, `task py:test`.

## Pitfalls
- Back up first (Admin → Backups). Recipes are irreplaceable family data.
- Use the API through the frontend's typed clients. Regenerate types after any schema change.
- Group/household scoping is automatic in repos. Don't bypass it with raw queries.

---
Machine-readable: [bespoke.yaml](https://handoff.bespokeai.software/p/mealie/581ac02/bespoke.yaml) · Agent skill: [SKILL.md](https://handoff.bespokeai.software/p/mealie/581ac02/SKILL.md)
