Gram
Code your recipes.
An open-source declarative and computational recipe DSL. Built to handle complex culinary logic, Gram compiles your plain-text instructions into structured, calculated, and relational data.
## Lemon Curd
[Mix] Whisk @lemon juice{100 g}<@lemons{3}, @eggs{2}, and @sugar{120% @&lemon juice} in a #saucepan{}. ->&base{}
[Cook] Heat the &base{} to ^{82C} over medium heat for ~{5m}.
[Emulsify] Remove from heat and blend in @butter{120 g}. Chill for ~_fridge{2h}.Design Philosophy
Gram is built to be simple to write, easy to version, and powerful to parse.
Plain Text & Git
No proprietary database or vendor lock-in. Your recipes are simple text files that can be versioned with Git, shared easily, and edited in any text editor.
Learn more →Automatic Calculations
Stop calculating hydration or portion sizes manually. The language natively handles arithmetic expressions, variable declarations, and unit conversions.
Learn more →Modular Recipes (@use)
Stop duplicating doughs, stocks, and sauces across files. Break shared sub-recipes into standalone files and import them anywhere with a single line.
Learn more →Dedicated IDE Support
Powered by a dedicated Language Server (LSP) giving you real-time diagnostics, semantic highlighting, and autocomplete directly in your IDE.
Learn more →Universal Export
Gram parses your recipes into a rich AST. Easily export them to JSON, Markdown, render them as HTML, or feed them into your favorite static site generator to build your own custom cookbook.
Learn more →Powerful CLI
Manage your workspace directly from the terminal. The official CLI lets you initialize projects, format files, and compile your recipes with ease.
Learn more →Gram in Practice
A few examples of how the compiler parses plain text into structured recipe data.
Database & Nutrition
Standardize measurements and calculate nutrition using a local database generated automatically from your workspace.Learn more →
---
portions: 4
---
## Chantilly Cream
[Whisk] @Heavy cream{1 cup} and @powdered sugar{2 tbsp} until soft peaks form.
[Fold] Gently incorporate @vanilla extract{1 tsp}.- WhiskHeavy cream (240g) and powdered sugar (25g) until soft peaks form.
- FoldGently incorporate vanilla extract (4g).
- of which sugars6.3 g
{
"shopping_list": [
{
"id": "heavy-cream",
"name": "heavy cream",
"qty": 1,
"unit": "cup",
"normalizedMass": 240,
"isEstimate": true,
"conversionMethod": "estimate"
},
{
"id": "powdered-sugar",
"name": "powdered sugar",
"qty": 2,
"unit": "tbsp",
"normalizedMass": 300,
"isEstimate": true,
"conversionMethod": "estimate"
},
{
"id": "vanilla-extract",
"name": "vanilla extract",
"qty": 1,
"unit": "tsp",
"normalizedMass": 300,
"isEstimate": true,
"conversionMethod": "estimate"
}
]
}ALAP Scheduling
Extracts duration metadata to build an execution timeline, scheduling passive tasks 'As Late As Possible'.Learn more →
## Tomato Basil Pasta
[Boil] The @pasta{200g} in salted water for ~_boiling{10min}. ->&cooked pasta{}
[Sauté] @cherry tomatoes{200g} and @garlic{2 cloves} in @olive oil{} for ~{5min}. ->&sauce
[Toss] The &cooked pasta{} into the hot &sauce with @fresh basil{1 handful}.{
"metrics": {
"totalTime": 19,
"totalBreakdown": [
{
"label": "timer_named:boiling",
"duration": 10
},
{
"label": "section_active:Tomato Basil Pasta",
"duration": 2
}
],
"idleTime": 5,
"activeTime": 7,
"activeBreakdown": [
{
"label": "section_active:Tomato Basil Pasta",
"duration": 7
}
],
"preparationTime": 7,
"prepBreakdown": [
{
"label": "ingredients_overhead",
"duration": 7
}
]
}
}Modular Recipes (@use)
Import shared base preparations with @use. Gram resolves dependencies, inlines preparation steps into the recipe, and scales quantities automatically.Learn more →
@use "./bases/shortcrust.gram" as &crust
## Lemon Tart
[Line] The #tart ring{} with &crust{250g}.
[Bake] Blind bake for ~_oven{18min} at ^{175C}.
[Fill] Pour in the @lemon curd{300g}.Crust
📦 bases/shortcrust.gram → crust (×0.5)- MixThe flour (125g), butter (62.5g), powdered sugar (45g), and water (17.5g).
Lemon Tart
- LineThe tart ring with &crust (250g).
- BakeBlind bake for 18min at 175°C.
- FillPour in the lemon curd (300g).
{
"modules": [
{
"binding": "crust",
"uri": "./bases/shortcrust.gram",
"scaleFactor": 0.5,
"mode": "inline"
}
],
"sections": [
{
"title": "Crust",
"intermediate_preparation": "crust",
"module": {
"binding": "crust",
"uri": "./bases/shortcrust.gram"
},
"ingredients": [
{
"id": "flour",
"qty": 125,
"unit": "g"
},
{
"id": "butter",
"qty": 62.5,
"unit": "g"
},
{
"id": "powdered-sugar",
"qty": 45,
"unit": "g"
},
{
"id": "water",
"qty": 17.5,
"unit": "g"
}
]
},
{
"title": "Lemon Tart",
"ingredients": [
{
"type": "reference",
"id": "crust",
"qty": 250,
"unit": "g"
},
{
"id": "lemon-curd",
"qty": 300,
"unit": "g"
}
]
}
]
}Baker's Math & Precision
Supports baker's percentages. Declare ingredients relative to a base ingredient to easily scale your recipes.Learn more →
## Country Loaf
[Mix] The @*bread flour{400g}, @whole wheat flour{100g}, @water{75% @&bread flour}, @salt{2% @&bread flour}, and @levain{20% @&bread flour}.{
"shopping_list": [
{
"id": "bread-flour",
"name": "bread flour",
"modifiers": [
"bakers_percentage"
],
"qty": 400,
"unit": "g",
"normalizedMass": 400,
"isEstimate": false,
"conversionMethod": "physical",
"bakersPercentage": 100
},
{
"id": "whole-wheat-flour",
"name": "whole wheat flour",
"qty": 100,
"unit": "g",
"normalizedMass": 100,
"isEstimate": false,
"conversionMethod": "physical",
"bakersPercentage": 25
},
{
"id": "water",
"name": "Water",
"relative": true,
"normalizedMass": 300,
"isEstimate": false,
"conversionMethod": "relative",
"qty": 300,
"unit": "g",
"bakersPercentage": 75
},
{
"id": "salt",
"name": "Salt",
"relative": true,
"normalizedMass": 8,
"isEstimate": false,
"conversionMethod": "relative",
"qty": 8,
"unit": "g",
"bakersPercentage": 2
},
{
"id": "levain",
"name": "levain",
"relative": true,
"normalizedMass": 80,
"isEstimate": false,
"conversionMethod": "relative",
"qty": 80,
"unit": "g",
"bakersPercentage": 20
}
]
}Get Involved
Explore the Language
The official documentation provides a complete guide to Gram's syntax, tooling, and inner workings. Ideal for getting started or deep-diving into the language.
Read the docs →Contribute
Gram is built openly and collaboratively. You can browse the source code, report issues, or submit patches to the compiler and documentation.
View on official repository →Start Cooking
Scaffold a new recipe workspace in seconds. The CLI sets up everything you need to start writing Gram locally.
$ npx @gram-lang/cli init