Features
- Bulk Food Import via paste JSON or upload CSV (Settings → Import & Export)
- Live nutrition preview on the Add to Diary sheet (macros update with portion / unit / servings)
- Mass-aware unit conversion when scaling nutrition (g ↔ oz ↔ lb, ml ↔ cup, tsp ↔ tbsp)
- Custom Units in Settings (“shot”, “scoop”, “stick”, etc.)
- Scan Label: snap a photo of a nutrition label and the AI Assistant fills in the values
- Smart Share / View on OFF: existing Open Food Facts products link straight to their wiki page for editing; new ones get a Share button to contribute back
- Connection status banners across every integration with one-tap Test / Sync / Disconnect
- Settings auto-save by default; no Save button to remember
- Day rollover at midnight when the app stays open overnight
- Barcode scanner now fully on-device on Android, no Google Play Services required (works on GrapheneOS / CalyxOS / e/OS)
- Custom nutriment order from Settings is reflected everywhere (food editor, meal editor, diary nutrition bar)
- Vitamin D, Calcium, Iron, and Potassium visible by default on new installs (FDA Nutrition Facts label mandatory fields)
- Svelte 5 + Vite 6 + Express 5 + bcryptjs 3 framework upgrade (main bundle ~22% smaller)
Fixes
- Disabling user management no longer triggers the setup wizard on every reload (#34)
- Data APIs in single-user mode no longer return 503 “Setup required” on every call (#34 part 2)
- Single-user mode: only the first food item added each day was visible in the UI. SQLite quirk on null
user_id. Includes a one-time migration that recovers items already in the database (#37) - Food saves on Android no longer duplicate the previous food (#32)
- “Most Used” / “Recently Used” food sort on Android now reflects real usage
- MyFitnessPal Reports → Export CSV imports cleanly now (aggregate-per-meal shape)
- Wellness scores refresh if today’s sleep finishes syncing after the morning snapshot
- Import Nutrition History action row no longer overlaps the duplicate-date radios (#33)
- Barcode scanner no longer gets stuck re-opening the camera after a scan
- Barcodes that don’t match anything in OFF now drop you in the food editor with the code prefilled instead of a dead-end toast, so you can contribute the product back
- Open Food Facts contribution now sends correct per-serving values and uploads your product image (both were silently broken)
- AI Assistant respects
AI_ENABLED=trueand the fullAI_*env-var set; toggle, settings card, and chat all honour the proxy (#36) - kcal / kJ values are consistent everywhere now: food editor, diary footer, meal totals, statistics, goals, weekly summary email, push notifications (#38)
- AI Assistant Gemini models updated to 2.5 Flash + Lite (Google retired 2.0 Flash and 1.5 Flash)
- nodemailer updated to 8.0.7 (patches an SMTP command-injection advisory)
- Several smaller things, see the full changelog
Signed APK + docker image on the release page.
Self-hosted, AGPL-3.0, no telemetry, no account needed. docker compose up and go.



That is correct, and it is called out in the README under Apps → iOS and in the Support section at the bottom. iOS needs a Mac, an iPhone, and a paid Apple Developer account, none of which I currently have. The Support section is where I mention that donations go toward exactly that. Apple Health sync specifically needs a native iOS wrapper since the data isn’t exposed to PWAs, so it has to wait on the same blocker. I hope to someday get this out to the community.