Grid Quickstart
Grid Quickstart
Goal: write your first Grid model and see it compute. About 10 minutes.
Prerequisites
You need:
- Node.js 20+
- A clone of the Grid repo
npm installalready run in the repo root
This walkthrough uses local validation, so you can see the model compute without configuring deployment infrastructure.
1. Write Your First Cells
Create a file hello.grid anywhere:
A1 = 10
A2 = 20
A3 = A1 + A2That's already a valid model. A3 evaluates to 30 whenever A1 or
A2 change.
Compile it to see what Grid produces:
npm run compile:model hello.gridYou'll see a generated runtime artifact printed to stdout. The compile step parses, builds the dependency graph, and confirms the model can run.
2. Add A Header
Real models start with a metadata header. Update hello.grid:
MODEL "Hello"
DESCRIPTION "A first Grid model."
VERSION "0.1.0"
AUTHOR "you@example.com"
A1 = 10
A2 = 20
A3 = A1 + A2
END MODELThe header has no semantic effect on cell values, but it's required by linters and the canonical style guide.
3. Use Functions And Type Tags
Replace the body with this:
A1 as currency = 125000
A2 as currency = 86000
B1 as currency = A1 - A2
B2 as percentage = B1 / A1
B3 = ROUND(B2 * 100, 1)What just happened:
as currencyandas percentageare type tags. They tell consumers (formatters, validators, the UI) what the value means semantically.ROUNDis one of 548 built-in functions. Seefunctions.mdfor the full catalog.B2will format as a percentage in the UI;B3will format as a plain number rounded to 1 decimal place.
4. Branch With THEN ... ELSE
Grid's preferred conditional is THEN ... ELSE:
C1 = B1 > 50000 THEN "strong" ELSE "watch"For multiple tiers, chain right-to-left from most-specific to
least-specific (chained THEN ... ELSE must be on one line):
C2 = B2 > 0.5 THEN "great" ELSE B2 > 0.3 THEN "good" ELSE "weak"If you're matching the same value against several alternatives, use
MATCH:
C3 = MATCH(C1, "strong" -> :green, "watch" -> :amber, _ -> :red)MATCH is a function call, so it can also wrap across lines:
C3 = MATCH(C1,
"strong" -> :green,
"watch" -> :amber,
_ -> :red
)Multi-line rule. Grid is line-oriented at the top level, but any expression inside
(...),[...], or{...}may span multiple lines. Block forms —DO,CASE WHEN,WHEN/EVERY/AT,WITH— also span lines. Seereference.md.
The :green, :amber, :red are symbol literals — enum-like labels.
5. Local Bindings With DO
When a formula gets long, name intermediate values with DO ... END:
B4 as currency = DO
margin = B1
deduction = 2500
MAX(margin - deduction, 0)
ENDThe last expression in a DO block is the value of the block.
6. Handle Missing Or Failing Values
Use DEFAULT for blank-or-error fallback:
A5 = BLANK
B5 = A5 DEFAULT 0 # → 0For division-by-zero or other errors, use IFERROR or TRY:
B6 = IFERROR(A1 / 0, "n/a") # → "n/a"
B7 = TRY 10 / 0 ELSE 0 # → 0See errors.md for the full error model.
7. Try Arrays
Grid arrays spill — a formula returning an array writes a rectangle of cells anchored at its target.
D1 = [120, 135, 142, 150, 168] # spills into D1:D5 horizontally
E1 = D1 * 1.1 # broadcasts; spills into E1:E5
F1 = SUM(D1#) # D1# is the entire spilled arrayHigher-order helpers work with arrays:
G1 = MAP(D1#, x => ROUND(x * 1.05, 2))
G2 = REDUCE(0, D1#, (acc, x) => acc + x)
G3 = SCAN(0, D1#, (acc, x) => acc + x)8. Call An External Function
External functions cross the runtime boundary — they enqueue a job and
write back asynchronously. Three are built in: FX_RATE, HTTP_JSON,
ML_SCORE.
H1 = FX_RATE("EUR", "USD")
H2 = ROUND(125000 * (H1 DEFAULT 1.08), 2)While the worker is fetching the rate, H1 is queued or running,
not ready. The DEFAULT 1.08 keeps H2 computable in the meantime.
For a value you only want to compute on demand, use ~=:
H3 ~= ML_SCORE([0.12, 0.18, 0.27, 0.43])H3 will not enqueue work until something reads it.
See external-functions.md for the full
async semantics.
9. Add A Rule
Rule blocks run on the Grid runtime. The scheduler orchestrates rule
waves and arms smart wakeups for EVERY/AT schedules, so the same
model behaves identically in local validation and hosted execution:
MODEL "Hello With Rules"
VERSION "0.2.0"
A1 = 0
WHEN A1 > 100 THEN
C1 = "over-limit"
C2 = NOW()
ENDWhenever A1 becomes greater than 100, the rule fires atomically: both
C1 and C2 are set in the same wave.
For periodic actions:
EVERY duration"PT15M" SKIP MISSED THEN
E1 = E1 + 1
ENDFor a one-shot action at a specific time:
AT dt"2026-12-31T23:59:00Z" BACKFILL THEN
G1 = TRUE
ENDSee rules-and-schedules.md for the full
rule semantics, including missed-run policy.
10. Run It For Real
To deploy the model into a running Grid, use the API URL for your Grid:
curl -X POST https://<your-grid-url>/api/models \
-H "Content-Type: application/json" \
-d "{\"id\": \"hello\", \"source\": $(jq -Rs . < hello.grid)}"
curl https://<your-grid-url>/api/models/helloTo write an input value:
curl -X PUT https://<your-grid-url>/api/models/hello/input \
-H "Content-Type: application/json" \
-d '{"symbol": "A1", "value": 200000, "typeTag": "currency"}'See docs/api/http_api.md for the full HTTP
contract.
What To Read Next
reference.md— every literal, operator, and expression form.assignments.md— every assignment shape.style-guide.md— the canonical authoring style.cookbook.md— recipes by task.
If you're an LLM agent generating Grid code from natural language,
start at ai-agent-guide.md.