Hi everyone! Gram v1.2.0 is now available, and it marks an important step forward for the language. Until now, recipes in Gram were always written as standalone, monolithic files. With this release, Gram introduces modular recipes through the @use directive — unlocking the ability to build and compose dishes from reusable sub-recipes and base preparations.
Here is an overview of what’s new and how modular recipes work in practice.
Modular recipes & @use imports
Complex dishes often rely on base preparations: a shortcrust pastry, a pastry cream, a starter, or a stock. Rather than copy-pasting those steps into every recipe, the @use directive lets you import external .gram files directly:
Rather than treating imports as plain text concatenation, the compiler composes modules into a single unified recipe graph:
- Timeline Interleaving: Steps from imported files interleave directly into the global ALAP scheduling timeline. Resting times and passive waiting periods from a base fit alongside other active preparations without losing retro-planning.
- Automatic Yield Scaling: Requesting a specific quantity (like
&shortcrust{250g}against a base that naturally yields 500 g) automatically scales the whole imported module to match, without requiring manual calculations. - Destructured Imports: Base recipes producing multiple usable components can be destructured cleanly:
@use "./bases/tart-elements.gram" as { &crust, &frangipane }, with each part scaling against its own yield. - Path Aliases & Project Roots: Beyond relative paths (
./,../), you can import from the project root (@/bases/...) or configure custom aliases underpaths:in.gram/config.yaml. - Stock Mode (
--stock): If a base preparation is already on hand (bought ready-made or prepped in advance),--stock @bases/shortcrust-pastry.gramremoves its steps from the timeline while still sourcing nutrition and mass from the base’s actual ingredients. - Retro-Planning on Imports: Base recipes requiring a head start (such as sourdough feeding or overnight marinating) can specify an offset directly on the
@useline:@use "./bases/starter.gram" as &starter ~{-2d}.
IDE & language server support
The VS Code extension and Language Server now resolve @use imports while typing:
- Live Preview & Gantt: The live preview and timeline reflect the fully composed recipe, including yield-scaled ingredients and imported steps.
- Go to Definition: Jumping to definition on an imported intermediate (
&shortcrust) opens the base recipe directly at the section that produces it. - Path Autocompletion: Typing
@use "completes relative paths, project aliases, and available.gramfiles. - Diagnostic Quick-Fixes: Importing an intermediate that isn’t exported yet suggests adding the missing
-> &nameexport with a single click.
Try it live in the playground
The online Playground has been updated with full multi-file support:
- You can now edit multiple
.gramfiles side by side using tabs, testing@useimports and live preview composition directly in your browser with no installation required. - A pre-configured multi-file example (Lemon Tart) is available directly in the preset dropdown to explore how imports, yield-scaling, and scheduling work together.
- You can also create new tabs to experiment with your own modular recipes!
Update checks & gram upgrade
- Passive Update Notice: The CLI checks npm in the background and prints a short notice when an update is available (skipped in CI and non-interactive runs). You can opt out with
updateCheck: falsein.gram/config.yamlor viaGRAM_NO_UPDATE_CHECK=1. - On-Demand Upgrades: Run
gram upgradeto check for and install the latest version interactively.
Diagnostics console & playground UI
- Diagnostics Console: The web playground consolidates compilation diagnostics into a bottom drawer with filter tabs (Errors, Warnings, Notices) and jump-to-location links.
- Mobile Layout: Added responsive tabs (
[Editor]/[Preview]) for narrower viewports. - Message Clarity: Compiler diagnostics have been revised for clearer phrasing, and non-blocking notices (such as missing macro data or track contention) are now categorized as informational.
Other fixes & tweaks
- Composite Ingredient Collision Checks: The compiler and
gram db syncnow warn when generic composite child names (e.g.@juice<@lemon) collide across different parents within the same recipe or collection. - Scaling Fixes:
gram scalenow correctly scales alternative ingredient groups (@butter|@margarine) and composite parent-draw quantities. - Nutritional Totals: Spliced intermediate masses (
-> &) are now consistently included in overall recipe nutrition and weight totals. - Section-Scoped Cycle Detection: Fixed false circular reference warnings when multiple sections independently used percentage-of formulas on same-named ingredients.
For the full list of changes and commit history, check out the Changelog. We’d love to hear your feedback!