BACK

YumML - Yet Another Recipe Metadata Format

12 min read

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.


XKCD: Standards

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 Valencia
Categories: beverages, spanish
Yield: 4 servings
1 bottle of spanish cava
-(sparkling wine or; champag
plenty fresh orange juice
cointreau
ice cubes
Put some ice cubes into a large jug and pour over lots of orange juice. Now
add the bottle of cava. Once the fizz subsides, stir in a good dash of the
cointreau and it's ready to serve.
Contributor: Esther Pérez Solsona
NYC 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 Cookies
date: 2011-09-21
prepTime: 15 minutes
cookTime: 10 minutes
ingredients:
- quantity: 2.5
unit: cups
item: plain flour
- quantity: 0.5
unit: tsp
item: bicarbonate of soda
instructions:
- 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.

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.

AttributeTypeStatusDescription
namestringREQUIREDName of the recipe
datestringOPTIONALPublication date (RFC 3339 format, e.g., 2017-07-21)
authorstringOPTIONALAuthor of the recipe
descriptionstringOPTIONALBrief description of the recipe
prepTimedurationOPTIONALPreparation time (e.g., 15 minutes)
cookTimedurationOPTIONALCooking/baking time (e.g., 10 minutes)
totalTimedurationOPTIONALTotal time (MAY be derived from prepTime + cookTime)
servingsintegerOPTIONALNumber of portions the recipe serves
yieldstringOPTIONALWhat the recipe produces (e.g., 24 cookies, 1 loaf)
ratingnumber (1-5)OPTIONALRecipe rating
tagsstring[]OPTIONALCategorization 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 Cookies
date: 2011-09-21
author: Paul Jenkins
description: Classic chocolate chip cookies, crispy outside and chewy inside.
prepTime: 15 minutes
cookTime: 10 minutes
servings: 4
yield: 24 cookies
tags:
- cookies
- chocolate
ingredients:
- quantity: 2.5
unit: cups
item: plain flour
- quantity: 0.5
unit: tsp
item: bicarbonate of soda
instructions:
- 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.

AttributeTypeStatusDescription
quantitynumber | stringOPTIONALAmount (number, fraction like "1/2", or descriptor like "to taste")
unitstringOPTIONALUnit of measurement (see canonical units below)
itemstringREQUIREDName of the ingredient
notesstringOPTIONALAdditional notes (e.g., room temperature, finely chopped)
optionalbooleanOPTIONALWhether the ingredient is optional (default: false)

Canonical Units

To support conversion between metric and imperial systems, implementations SHOULD recognize these canonical unit abbreviations:

CategoryUnits
Volumetsp, tbsp, cup, ml, l, fl-oz
Weightg, kg, oz, lb
Count(omit unit for countable items like eggs)

Example

ingredients:
# Numeric quantities
- quantity: 2.5
unit: cups
item: plain flour
- quantity: 200
unit: g
item: chocolate chips
notes: semi-sweet
# Fraction string (more readable than 0.5)
- quantity: "1/2"
unit: cup
item: walnuts
notes: chopped
optional: true
# Countable items (no unit needed)
- quantity: 2
item: eggs
notes: room temperature
# Descriptor string for fuzzy amounts
- quantity: "to taste"
item: salt
# No quantity (implied "some")
- item: cooking spray
notes: 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

AttributeTypeStatusDescription
stepstringREQUIREDThe instruction text
durationdurationOPTIONALTime for this step
temperaturestringOPTIONALTemperature setting (e.g., 180C, 350F)
instructions:
- step: Preheat oven
temperature: 180C
- step: Mix dry ingredients in a large bowl
- step: Bake until golden brown
duration: 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 section to determine the format: if any item has a section field, treat as grouped; otherwise, treat as simple.

instructions:
- section: For the dough
steps:
- step: Mix flour and salt
- step: Add water gradually
- section: For the filling
steps:
- step: Sauté onions until translucent
duration: 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 Pie
date: 2024-03-15
author: Jane Baker
description: A traditional apple pie with a flaky butter crust and cinnamon-spiced filling.
prepTime: 45 minutes
cookTime: 55 minutes
totalTime: 1 hour 40 minutes
servings: 8
yield: 1 pie (9-inch)
rating: 5
tags:
- dessert
- pie
- baking
ingredients:
- quantity: 2.5
unit: cups
item: all-purpose flour
- quantity: 1
unit: tsp
item: salt
- quantity: 1
unit: cup
item: unsalted butter
notes: cold, cubed
- quantity: 6
unit: tbsp
item: ice water
- quantity: 6
item: apples
notes: peeled and sliced (Granny Smith recommended)
- quantity: 0.75
unit: cup
item: sugar
- quantity: 2
unit: tsp
item: cinnamon
- quantity: 0.25
unit: cup
item: caramel sauce
optional: true
instructions:
- section: For the crust
steps:
- 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 refrigerate
duration: 30 minutes
- section: For the filling
steps:
- step: Preheat oven
temperature: 375F
- step: Toss sliced apples with sugar and cinnamon
- step: Roll out bottom crust and place in pie dish
- section: Assembly
steps:
- 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 bubbling
duration: 55 minutes
temperature: 375F
- step: Cool before serving
duration: 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.