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.gram
## 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 →

input.gram
---
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}.
  1. WhiskHeavy cream (240g) and powdered sugar (25g) until soft peaks form.
  2. FoldGently incorporate vanilla extract (4g).
NutritionEstimate
Per portionPer 100 gWhole recipe
Calories231 kcal
Fat22 g
Carbohydrates6.5 g
  • of which sugars6.3 g
Fiber0 g
Protein1.5 g
Sodium11 mg
{
  "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 →

input.gram
## 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}.
Total Time: 17m · Active: 7m
Actions
Prep Time
Sauté
↳ Toss
Boiling
10m
0m
5m
10m
15m
17m
{
  "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 →

input.gram
@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)
  1. MixThe flour (125g), butter (62.5g), powdered sugar (45g), and water (17.5g).

Lemon Tart

  1. LineThe tart ring with &crust (250g).
  2. BakeBlind bake for 18min at 175°C.
  3. 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 →

input.gram
## Country Loaf

[Mix] The @*bread flour{400g}, @whole wheat flour{100g}, @water{75% @&bread flour}, @salt{2% @&bread flour}, and @levain{20% @&bread flour}.
Bread Flour - 400g100%
Whole Wheat - 100g25%
Water - 375g75%
Levain - 100g20%
Salt - 10g2%
{
  "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