Sub-entries (dishes & ingredients)
A Property kind that lets one Entry hold a list of other Entries — a dish made of ingredients, a recipe of steps, a meal of foods. The ingredients vary every time, and each one is a real Entry that rolls up on its own.
Most Property kinds answer "what did you log?" with a number, some text, or a yes/no. Sub-entries answers it with other Entries. It's the "this thing is made of other tracked things" kind — the way you log a dish and the ingredients inside it.
The headline case is food: a Dish Type with one Sub-entries Property called Ingredients. Log a dish, and you add whatever foods went into it — a hamburger today (beef, buns, sauce), a salad tomorrow (tomato, broccoli, olive oil). The ingredients change every single time, and that's the point.
The key idea: ingredients aren't fixed to the Type
This is what makes Sub-entries different from a Routine, which logs the same set of Types every time. With Sub-entries:
- The Dish Type only says "entries of this Type can hold ingredients." It never decides which ingredients.
- Each dish Entry holds its own, chosen as you log it.
- The same Dish Type produces a hamburger one day and a salad the next.
So you build one Dish Type, and every dish you log is free to contain anything. (If a Type's children are usually the same, you can give it a default starting set — still editable on every entry.)
How it works in the app
1. Add the Sub-entries Property. In the Type builder, add a property and pick Sub-entries from the Other group. Give it a name that suits the Type — Ingredients for a dish, Steps for a recipe. That's the only extra property a dish needs — the macros live on the foods, not the dish.
2. Log a dish. Create a Dish Entry. Its card shows an Ingredients list with a + Add button.
🍽 Hamburger
Ingredients
+ Add
3. Add ingredients. Tap + Add and search your foods. Pick an existing one (🧀 Mozzarella) or type a new name to create it on the spot. Each pick becomes a child entry under this dish.
🍽 Hamburger
Ingredients
🥩 Beef ✕
🍞 Buns ✕
🥫 Sauce ✕
+ Add
4. Fill in each ingredient's details. An ingredient is a normal Entry of its food Type with its own Properties (grams, calories, …). On the dish's own page each ingredient is a toggle — click the ▸ triangle to collapse it to a single line, or expand it to edit its fields right there. They start expanded, so opening a "Sets" entry shows every set's reps ready to edit without leaving the page. (You can still click an ingredient's name to open its own full page.)
Remove an ingredient with the ✕; delete the whole dish and its ingredients go with it.
Compact or full
By default the ingredient list is compact — one line per ingredient (emoji + name), like a checklist. If you'd rather see each ingredient's full detail — its macros and fields — right on the card, switch the Ingredients property to Full cards:
Open the Dish Type → Properties tab → the Ingredients row → the Compact / Full dropdown.
In Full mode each ingredient renders as its own mini card (the same layout a routine log uses for its entries), and you can edit an ingredient's numbers right there. Compact is best for long lists; Full is best when you want the macros visible at a glance.
Start every entry with the same sub-entries
Sometimes a Type's children barely change — a Bench press that's always three Sets, a Smoothie that always starts from the same base. Instead of adding them by hand every time, give the Type a default sub-entries list, and every new entry is born with them already attached.
Open the Type → Properties tab → the Sub-entries row → Add default sub-entry. Search your Types (or create one on the spot), and it joins the starting set. Click a default to expand it and preset its values — a "Set" that always starts at 10 reps, say.
When you then log that Type, the entry already contains those children — and you're still free to add more, remove them, or change their numbers for that one entry. It's a head start, not a fixed line-up:
- Editing the defaults later only changes new entries — ones you already logged keep whatever they had.
- Each default child is created with its own Type's defaults first, then your preset values on top.
- It goes one level deep: if a default child's Type also has defaults of its own, those aren't expanded.
- It works everywhere a log is created — the quick logger and the AI assistant included.
Why each ingredient is its own Entry
When you add "Mozzarella" to a dish, you're not typing a word — you're logging a Mozzarella Entry that happens to live inside the dish. That one design choice unlocks the analysis:
- Your daily calories include every ingredient automatically — a banana eaten on its own and a banana inside a smoothie count exactly the same.
- "How much cheese did I eat this year?" is a chart on the Mozzarella Type — every dish's mozzarella is a real Mozzarella Entry, so they all add up.
- No double-counting. The dish itself carries no macros; the numbers live on the ingredients, so totals are counted once.
This is the universal engine doing its job: ingredients are just Entries, and Entries roll up.
Dish as one entry, or broken down — your call
You don't have to break every meal into parts:
- Flat — for a restaurant meal you only know the total of, give the Dish its own Calories/Protein Properties and type the total. One Entry, done.
- Broken down — for a homemade meal, leave the macros off the dish and add ingredients with their own numbers.
Pick per meal. A quick photo-style "≈850 kcal pizza" is flat; "200g dough, 150g mozzarella, 80g sauce" is broken down.
Examples
🍔 Dish — Ingredients (Sub-entries). The everyday meal log; name each one as you go (Hamburger, Salad, Stir-fry).
🥗 Recipe — Ingredients (Sub-entries) · steps (Markdown) · servings (Number). A reusable recipe with its parts and method.
🛒 Shopping trip — Items (Sub-entries) · total (Number). Each item is its own Entry with a price.
🎒 Packing list — Items (Sub-entries) · packed (True/false on each item). What went in the bag this trip.
Sub-entries vs Relation vs Routine
All three connect things, but they're for different jobs:
| Kind | What it does | Example | |------|--------------|---------| | Sub-entries | Holds child Entries this entry owns | A dish's ingredients | | Relation | Points at another Entry that stands on its own | A reading session → the Book it's from | | Routine | Logs the same set of Types together every time | Morning ritual: meditation + stretch + journal |
Use Sub-entries when the parts belong to this one thing and change each time. Use Relation to link to something independent. Use a Routine when the line-up is always the same.
Next
- Properties and the Title — the full catalogue of Property kinds
- What is a Routine — for a fixed line-up logged together
- Reading your rollups — chart "kg of cheese this year" and daily macros