Recipe format
Recipes are plain text in a Markdown variant the app parses into title, ingredients, steps, and notes. Write by hand, paste from another source, or use the graphical editor — the file on disk is the same shape either way.
A complete example
# Pancakes
Fluffy weekend pancakes.
Category: Breakfast
Tags: quick, weekend
Makes: 12 pancakes
Serves: 4
Time: 25 min
Active: 15 min
## Mix the batter.
- Flour (all-purpose), 190 g
- Milk, 240 g
- Eggs, 2
- Butter, 2 tbsp: Melted.
Whisk dry ingredients. Add wet ingredients and stir until just combined.
## Cook the pancakes.
- Butter
Pour about 60 g of batter per pancake onto a hot buttered pan.
Cook until bubbles form and edges look set. Flip and cook 1 minute more.
---
Try adding blueberries or chocolate chips to the batter.
Title
The first non-blank line, marked with #. Required.
# Pancakes
Description
An optional paragraph that appears as a subtitle on the recipe page. Place it between the title and the first step. In recipes that use explicit ## step headers, lines between front matter and the first step also count as the description, so the order of description and front matter is flexible. (In recipes without ## headers, prose after front matter is parsed as the implicit step instead.)
# Pancakes
Fluffy weekend pancakes.
Front matter
Optional lines before the first step. Each line is one key, a colon, at least one space, and a value — no leading whitespace.
| Line | Example | Notes |
|---|---|---|
Category: |
Category: Breakfast |
One per recipe. Overrides the category chosen when creating |
Tags: |
Tags: quick, weekend |
Comma-separated. Each tag is lowercased; runs of whitespace become hyphens (slow cooker → slow-cooker) |
Makes: |
Makes: 12 pancakes |
What the recipe produces. Requires a unit noun; Makes: 12 alone is rejected |
Serves: |
Serves: 4 |
Number of servings. Used for per-serving nutrition |
Time: |
Time: 1 hour 30 min |
Total time from start to plated. Accepts forms like 30 min, 1h, 2 hours 30 min |
Active: |
Active: 30 min |
Hands-on portion of Time:. Requires Time: to be set; can’t exceed it |
Makes: and Serves: can appear together — Makes: 1 loaf paired with Serves: 12 is valid.
Steps
Each step starts with a ## heading. The heading text is a short label that appears as a section header on the recipe page. Periods at the end (## Mix the batter.) are convention in the sample recipes, not a parser requirement.
## Mix the batter.
- Flour, 190 g
- Milk, 240 g
Whisk until smooth.
A recipe with ingredients but no ## headings is still valid — the parser treats the whole body as a single implicit step.
Ingredients
Ingredient lines start with - . The shape is:
- Name, quantity: prep note
- Name — matched against the ingredient catalog for grocery tracking
- Quantity — optional. Numbers, units, ranges, fractions, or unicode glyphs
- Prep note — optional. Renders in smaller text below the line
Examples:
- Butter ← name only
- Flour (all-purpose), 190 g ← name and quantity
- Eggs, 2 ← name and count
- Eggs, 1-2 ← name and range
- Milk, ½ cup ← unicode fraction
- Butter, 2 tbsp: Melted. ← name, quantity, and prep note
Supported unicode fraction glyphs: ½ ⅓ ⅔ ¼ ¾ ⅛ ⅜ ⅝ ⅞. Mixed forms like 1½ or 1 1/2 work too. Ranges accept -, –, —, or − between numbers. When you scale the recipe, a range scales from its high end — scaling 1-2 by 2 gives 4.
The colon and comma are reserved delimiters. The first colon starts the prep note; everything before it is the name and quantity, split at the first comma. (A comma after the colon stays in the prep note.) A comma inside parentheses doesn’t count, so Sugar (brown, packed), 150 g keeps its full name. To add a prep note without a quantity, use a colon — a comma puts the word in the quantity slot instead:
- Onion: diced ← prep note
- Onion, diced ← "diced" becomes the quantity
When two recipes share an ingredient, the grocery list combines the quantities. Two recipes calling for Flour, 190 g add up to 380 g on one line.
Cross-references
A step can pull in another recipe’s steps. Embedded form goes inside a step on its own line:
## Make the sauce.
> @[Simple Tomato Sauce]
A bare @[Recipe Title] in prose — step text or footer — renders as a clickable link without embedding. Full syntax, including multipliers and prep notes, is on Cross-references.
Scalable numbers
Append * to a number in step instructions, ingredient prep notes, cross-reference prep notes, or the footer to mark it as scalable. When a reader changes the serving count, marked numbers update.
Divide the dough into 8* equal pieces.
- Eggs, 2: Beat with a fork until uniform, about 30* seconds.
> @[Pizza Dough], 2: Make a double batch — about 90* minutes total.
---
Yields about 12* cookies.
Numerals, fractions, and English number words from zero* through twelve* are all scalable. See Scaling for what scales automatically without *.
Footer
The first --- on its own line ends the recipe body and starts the footer. Everything after it is rendered as plain Markdown — good for notes, sources, and variations. Because that first --- is reserved as the footer separator, you can’t use one as a thematic break between steps.
---
A good basic pancake. Pairs well with @[Maple Syrup].
Things to know
- Front-matter keys (
Category:,Tags:,Makes:,Serves:,Time:,Active:) parse only in the dedicated front-matter block right after the description (or right after the title if there’s no description). A correctly-formed stray (Serves: 4later in the recipe) is absorbed as plain prose; a malformed or invalid one (serves: 4lowercase,Serves:4no space,Serves: 0,Time: varies) is rejected with a clear error wherever it appears - When a recipe uses
##step headers, every ingredient bullet must sit under one. Bullets between the front matter and the first header are rejected; either move them under a header, or drop the headers and let the parser treat the body as one implicit step - A step that contains both a
> @[...]cross-reference and ingredients or instructions is rejected — the cross-reference must stand alone - Only one
> @[...]per step