YumML - Yet Another Recipe Metadata Format
Years ago, talking with a friend, we realized that no standard format exists for saving cooking recipes. At that time I was learning React, and one of my early projects was a recipe management app. I didn't succeed (like many projects I started and never finished), but along the way I found a draft spec for a recipe format: YumML.

Yes, I'm fully aware of the irony. xkcd.com/927
Paul Jenkins published this format on vikingco.de, but the site is now offline. The only references available are from the Internet Archive and the repository of the page that remains available.
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.
History
The first draft of the YumML format is from September 21, 2011, made by Paul Jenkins, you can check the original specification here that I rescued from the old archives I found.
This draft is promising as a format for cooking recipes, so I want to recover it from the forgotten archives and revive it, adding extra functionalities and specifications.
Motivation
As the original author of YumML mentioned in his blog post, I've investigated cooking recipe formats and, to be clear, most suck. The landscape of recipe interchange formats is fragmented, but most share one trait: they lack human readability.
Most cooking software ships with proprietary formats that only that software can read. Some can be imported by other programs. Meal-Master is one of these widely supported formats and due to that there is a huge collection of recipes available online.
But looking at an example, the format seems poorly specified:
MMMMM----- Now You're Cooking! v5.65 [Meal-Master Export Format]Title: Agua De ValenciaCategories: beverages, spanishYield: 4 servings1 bottle of spanish cava-(sparkling wine or; champagplenty fresh orange juicecointreauice cubesPut some ice cubes into a large jug and pour over lots of orange juice. Nowadd the bottle of cava. Once the fizz subsides, stir in a good dash of thecointreau and it's ready to serve.Contributor: Esther Pérez SolsonaNYC Nutrilink: N0^00000,N0^00000,N0^00000,N0^00000
There are some other "famous" formats like:
But they are mainly XML-based formats, and no human can read a recipe written in them. If you're interested in finding other recipe formats, there is a list of software-related cooking formats.
It's worth mentioning some formats that came with the age of the Internet. HTML microdata like Google rich snippets and schema.org microdata are widely used by commercial recipe sites. Although microdata's main objective is machine-readability (especially for SEO), people still read and follow recipes.
Finally, I found pesto, which aims for a simpler human-readable format, but I find it difficult to understand for someone who is unfamiliar with the syntax.
Original design considerations
The original author of YumML had some considerations in mind during the design of the format:
- Does not need a long reference guide.
- Can be easily read by non-technical people in the "raw" format.
- Can be translatable between imperial and metric.
- Want something like the markdown of recipes (but still easy to parse with software).
YumML is based on YAML to create a human and system readable format.
From yaml.org
What It Is: YAML is a human friendly data serialization standard for all programming languages.
Why YAML in the Age of AI
When the original YumML spec was drafted in 2011, the consideration was purely about human and machine readability. Today, there's a third reader to consider: Large Language Models (LLMs).
As AI assistants become common in kitchens (think voice assistants reading recipes aloud, or chatbots helping you adapt recipes), the format you choose for structured data matters more than ever. Recent research shows that data format significantly impacts both token efficiency (cost) and model accuracy when LLMs process structured information.
Benchmarks across different models show that YAML uses 27-40% fewer tokens than JSON and 38-40% fewer than XML for the same data. Beyond cost savings, format also affects comprehension: YAML achieved 12-18 percentage points higher accuracy than JSON when models extracted information from nested data. The cleaner syntax with less punctuation noise helps models parse semantic content more reliably. While minified JSON can be more efficient, it sacrifices human readability entirely, which defeats YumML's core goals.
The best of both worlds
YAML's design strikes a balance that works well for this three-way readability requirement:
- Humans can read it without training (no angle brackets or curly braces)
- Machines can parse it with standard libraries in any language
- AI models process it more efficiently and accurately than alternatives
This makes YumML particularly well-suited for modern recipe applications where an AI might help you scale a recipe, suggest substitutions, or convert between metric and imperial, all while keeping the source format readable in a text editor.
Goals
I want to define more formal goals for the spec.
YumML format:
- MUST be human and system readable.
- MUST be self contained, so it MUST NOT require additional resources to be interpreted.
- MUST have support for different metric systems (metric, imperial).
- SHOULD be easy to translate into different languages (recipes have a strong cultural influence and language should not be a barrier to someone who wants to understand).
- SHOULD be easy to parse using already existing tools.
- SHOULD be easy to extend in the future.
Technical Details
- File extension:
.yumml(files MUST be valid YAML) - MIME type:
application/x-yumml+yaml - Encoding: UTF-8
Basic Example
name: Mrs Fields Choc-Chip Cookiesdate: 2011-09-21prepTime: 15 minutescookTime: 10 minutesingredients:- quantity: 2.5unit: cupsitem: plain flour- quantity: 0.5unit: tspitem: bicarbonate of sodainstructions:- step: Mix flour, bicarbonate of soda, and salt in a large bowl- step: Blend sugars with electric mixer, add margarine to form a grainy paste
Spec
There are three main sections that every recipe MUST include: the header, the ingredients list, and the instructions.
Header
The header is an implicit section where all the attributes are placed at the
root level of the file. All the attributes SHOULD be placed at the top of
the file, before ingredients and instructions.
| Attribute | Type | Status | Description |
|---|---|---|---|
name | string | REQUIRED | Name of the recipe |
date | string | OPTIONAL | Publication date (RFC 3339 format, e.g., 2017-07-21) |
author | string | OPTIONAL | Author of the recipe |
description | string | OPTIONAL | Brief description of the recipe |
prepTime | duration | OPTIONAL | Preparation time (e.g., 15 minutes) |
cookTime | duration | OPTIONAL | Cooking/baking time (e.g., 10 minutes) |
totalTime | duration | OPTIONAL | Total time (MAY be derived from prepTime + cookTime) |
servings | integer | OPTIONAL | Number of portions the recipe serves |
yield | string | OPTIONAL | What the recipe produces (e.g., 24 cookies, 1 loaf) |
rating | number (1-5) | OPTIONAL | Recipe rating |
tags | string[] | OPTIONAL | Categorization tags |
Duration format: Human-readable strings. For maximum compatibility, use
integers followed by minutes, hours, or seconds (e.g., 15 minutes,
1 hour 30 minutes). Parsers SHOULD also accept common abbreviations
(15 min, 1 hr) and natural variations (1.5 hours).
Example
name: Mrs Fields Choc-Chip Cookiesdate: 2011-09-21author: Paul Jenkinsdescription: Classic chocolate chip cookies, crispy outside and chewy inside.prepTime: 15 minutescookTime: 10 minutesservings: 4yield: 24 cookiestags:- cookies- chocolateingredients:- quantity: 2.5unit: cupsitem: plain flour- quantity: 0.5unit: tspitem: bicarbonate of sodainstructions:- step: Mix flour, bicarbonate of soda, and salt in a large bowl- step: Blend sugars with electric mixer, add margarine to form a grainy paste
Ingredients
The ingredients section is a REQUIRED list of all ingredients needed for
the recipe.
| Attribute | Type | Status | Description |
|---|---|---|---|
quantity | number | string | OPTIONAL | Amount (number, fraction like "1/2", or descriptor like "to taste") |
unit | string | OPTIONAL | Unit of measurement (see canonical units below) |
item | string | REQUIRED | Name of the ingredient |
notes | string | OPTIONAL | Additional notes (e.g., room temperature, finely chopped) |
optional | boolean | OPTIONAL | Whether the ingredient is optional (default: false) |
Canonical Units
To support conversion between metric and imperial systems, implementations SHOULD recognize these canonical unit abbreviations:
| Category | Units |
|---|---|
| Volume | tsp, tbsp, cup, ml, l, fl-oz |
| Weight | g, kg, oz, lb |
| Count | (omit unit for countable items like eggs) |
Example
ingredients:# Numeric quantities- quantity: 2.5unit: cupsitem: plain flour- quantity: 200unit: gitem: chocolate chipsnotes: semi-sweet# Fraction string (more readable than 0.5)- quantity: "1/2"unit: cupitem: walnutsnotes: choppedoptional: true# Countable items (no unit needed)- quantity: 2item: eggsnotes: room temperature# Descriptor string for fuzzy amounts- quantity: "to taste"item: salt# No quantity (implied "some")- item: cooking spraynotes: for greasing
Instructions
The instructions section is a REQUIRED list of steps to prepare the
recipe. Instructions support two formats: a simple flat list or grouped sections
for complex recipes.
Simple Format
| Attribute | Type | Status | Description |
|---|---|---|---|
step | string | REQUIRED | The instruction text |
duration | duration | OPTIONAL | Time for this step |
temperature | string | OPTIONAL | Temperature setting (e.g., 180C, 350F) |
instructions:- step: Preheat oventemperature: 180C- step: Mix dry ingredients in a large bowl- step: Bake until golden brownduration: 10 minutes
Grouped Format
For complex recipes with multiple stages, instructions MAY be organized into sections:
Implementation note: Parsers MUST handle both formats. Check for the presence of
sectionto determine the format: if any item has asectionfield, treat as grouped; otherwise, treat as simple.
instructions:- section: For the doughsteps:- step: Mix flour and salt- step: Add water gradually- section: For the fillingsteps:- step: Sauté onions until translucentduration: 5 minutes- step: Add remaining filling ingredients
Design Notes
A few decisions deserve explanation.
Why quantity is optional and accepts strings
Cooking is fuzzy. Real recipes include instructions like "salt to taste", "a
pinch of nutmeg", or "butter for greasing". Forcing a numeric quantity would
either exclude these cases or push authors toward awkward workarounds like
quantity: 0.
Allowing strings also enables fractions like "1/2", which are more readable in
a recipe context than 0.5. The trade-off is that parsers need to handle
multiple types, but this reflects the inherent ambiguity of cooking rather than
fighting it.
Why human-readable durations instead of ISO 8601
ISO 8601 durations (PT25M) are unambiguous and machine-friendly, but they fail
the "readable by a non-technical person" goal. A home cook glancing at a
.yumml file should immediately understand 25 minutes without consulting a
reference.
The spec recommends a structured subset (integer + unit) for tools that need
reliable parsing but remains flexible enough to accept natural variations.
Why instructions support two formats
Simple recipes don't need sections. Forcing authors to write section: main for
a basic cookie recipe adds friction. But complex recipes (like a multi-component
pie) genuinely benefit from grouping steps by stage.
The polymorphic design prioritizes author convenience over parser simplicity.
The implementation note makes the parsing logic explicit: check for section to
determine the format.
Complete Example
Here's a comprehensive example demonstrating all YumML features:
name: Classic Apple Piedate: 2024-03-15author: Jane Bakerdescription: A traditional apple pie with a flaky butter crust and cinnamon-spiced filling.prepTime: 45 minutescookTime: 55 minutestotalTime: 1 hour 40 minutesservings: 8yield: 1 pie (9-inch)rating: 5tags:- dessert- pie- bakingingredients:- quantity: 2.5unit: cupsitem: all-purpose flour- quantity: 1unit: tspitem: salt- quantity: 1unit: cupitem: unsalted butternotes: cold, cubed- quantity: 6unit: tbspitem: ice water- quantity: 6item: applesnotes: peeled and sliced (Granny Smith recommended)- quantity: 0.75unit: cupitem: sugar- quantity: 2unit: tspitem: cinnamon- quantity: 0.25unit: cupitem: caramel sauceoptional: trueinstructions:- section: For the cruststeps:- step: Combine flour and salt in a large bowl- step: Cut in cold butter until mixture resembles coarse crumbs- step: Add ice water gradually, mixing until dough forms- step: Divide dough in half, wrap in plastic, and refrigerateduration: 30 minutes- section: For the fillingsteps:- step: Preheat oventemperature: 375F- step: Toss sliced apples with sugar and cinnamon- step: Roll out bottom crust and place in pie dish- section: Assemblysteps:- step: Add apple filling to crust- step: Roll out top crust and place over filling- step: Crimp edges and cut vents in top- step: Bake until golden brown and bubblingduration: 55 minutestemperature: 375F- step: Cool before servingduration: 30 minutes
What's Next
This spec is a starting point—to become useful, YumML needs implementations. If you're interested in contributing:
- Write a parser in your favorite language (TypeScript, Python, Go, Rust...)
- Build a converter from schema.org/Recipe to YumML
- Create a VS Code extension with syntax highlighting and validation
- Experiment with LLMs to see how well they can generate and parse YumML
If you build something, I'd love to hear about it.