CookTrace is a self-hosted recipe manager (Docker + Android, AGPL-3.0). rc.3 is the next public roll-up, bundling everything since the rc.1 first public release plus the rc.2 patches in between.
What’s new
- Pantry variants. A pantry row can now carry brand-specific rows underneath it. Recipes link to the generic parent (Whole Milk); each variant (Greenwise, Publix) has its own barcode, photo, stock, and expiration date. A generic can either use its own nutrition or pull from a chosen variant, so recipe math reflects the label of the product you actually cook with. Add Variant with inline suggestions from existing pantry rows; deleting a parent with variants asks whether to keep them as standalone items or remove them together.
- Pantry expiration dates + digest push. Every pantry row gains an Expires On field with amber/red pills and an “Expiring Soon” filter chip. A once-a-day roll-up delivers everything expiring within a chosen window (1 / 3 / 5 / 7 / 14 days) at a chosen time, through Apprise, Gotify, or ntfy plus the local device channel. Past-expiry items always included.
- AI Scan Label for pantry nutrition. Take a photo of a nutrition label from the pantry item editor and Trace extracts name, brand, serving size, and every nutrient it can read. Complementary to the existing barcode scanner: barcode → Open Food Facts lookup for name-brand products; label scan → store-brand jars, homemade batches, imports OFF doesn’t cover. Requires an AI provider configured in Settings.
- Shopping list aisle grouping + drag reorder. New chip row toggles between By Aisle, By Recipe, and Flat. Every pantry category picks up an optional Default Aisle label; items added from a linked pantry row inherit that aisle automatically. Custom aisles work as free-text groups (write “Freezer” once and it becomes a group). Rows drag to reorder within a group; cross-group drops in By Aisle mode reassign the moved item’s aisle, so shuffling the list is the same gesture as reclassifying an item.
- Simplified shopping quick-add + per-row edit. Primary add is now name plus optional qty plus a labeled Add pill, matching Google Keep, Bring!, AnyList, and OurGroceries. Unit moved to a per-row Edit modal so the sweep flow (“milk, eggs, bread”) is name-tap-Add-repeat rather than three fields per item. The two bulk-add sources (Recipe, Planned Cooks) collapse behind a single + button in the header.
- Recipe Rest Time + Total Time. New Rest Time field for hands-off periods (rise, rest, marinate, chill, soak, ferment) rolls into the auto-calculated Total Time. Optional manual override on Total Time when the recipe’s stated total is bigger than the components would imply. Times render as
1h 15macross list cards, recipe view, cookbook, public share, and the recipe-card image. - Multi-select on Pantry and Recipes. Long-press to enter selection mode. Header title flips to “N Selected” and top-right icons become trash + cancel on Pantry, or trash + add-to-cookbook + cancel on Recipes. Matches the pattern used on NutriTrace’s Diary + Foods. Replaces the older floating action pill.
- Mobile ingredient rows. The three per-row action buttons (link to pantry, section divider, delete) collapse behind a kebab menu on small screens so the ingredient name field has room to read. Adding a note is one tap in the kebab; the note appears on a second inline row.
- Four animated page banner styles. Retired the illustrated SVG headers in favor of Shimmer, Drift, Pulse, and Aurora gradient animations. All four honor Reduce Motion. Settings → Appearance → Banner Style.
Fixes
- Cook Mode now reliably keeps the screen awake on Android via the native KeepAwake plugin — the Web Wake Lock path silently stopped working on some Android WebView versions
- Cook photos taken during a diary log render immediately on the Diary Photos tab; older photos still render via a backstop URL conversion
- Bulk-add from a recipe or planned cook populates each row’s aisle from the linked pantry item’s category, so items land pre-grouped instead of piling into Uncategorized
- Long-pressing a shopping row no longer lets you drag it while the action menu is open — the finger-hold that opened the menu was feeding pointer moves into the reorder tracker
- Cancel out of Pantry multi-select no longer leaves an invisible layer blocking taps until reload
- The Shopping quick-add box no longer freezes on mobile when the pantry has hundreds of items — the suggestion list is now capped
- Last Cooked date no longer concatenates with a full timestamp
- Mealie ZIP importer extracts cook-event photos for full live-API parity
Security
- Dependency security bumps clear every actionable Dependabot alert:
multer1.4.5-lts.1 → 2.2.0 (three high-severity DoS CVEs on the LTS line),nodemailer8.0.7 → 9.0.3 (five CVEs including TLS OAuth cert-validation bypass and CRLF header injection),vite7.3.3 → 7.3.6 (dev-onlyserver.fs.denybypass), plus an esbuild override to clear a dev-server CORS advisory nested under svelte-i18n. Self-hosters on Docker just need to pull the new image.
Install / upgrade
- Docker: pull the new image and restart your stack (see the README for compose snippets)
- Android: signed APK on the release page
- Full CHANGELOG: main repo
What is CookTrace?
Self-hosted recipe manager. Full recipe library with live scaling, ingredient unit conversion, FDA-style Nutrition Facts, cook mode, and cook log. Pantry catalog with barcode scanning (ML Kit on Android, QuaggaJS on web), Open Food Facts + USDA lookup, variants, expiration dates, and an “8/10 in pantry” match pill on every recipe card. Cook diary + meal planner with list and month-calendar views. Shopping list that pulls missing ingredients from a recipe and skips anything you already have stocked. Trace AI assistant (Claude / OpenAI / Gemini / Ollama). Multi-user with OIDC SSO. Federation with NutriTrace (nutrition) and LiftTrace (lifting). Docker on the server, Capacitor app on Android. AGPL-3.0 licensed.

