Reactive Markdown
This page opts into the runtime because it declares state. Static pages ship zero framework JavaScript.
The count is 0.
The details are visible now.
The details are hidden.
The details are hidden.
Keyed loops over real objects
The same @loop that unrolls static data also drives reactive lists. Items are objects, bindings use dotted paths, and the runtime patches the list by key instead of re-rendering it:
- Route pages — PM
- Ship tiny runtime — Dev
Conditionals inside a loop, nested
:if works per row, and conditionals nest — the inner branch is decided after the outer one, for every item, and stays reactive. Add a "done" task and watch which badge each row shows:
—
done ✓
blocked ✗
in progress …
Draft the spec —
done ✓
blocked ✗
in progress …
done ✓
Wire the runtime —
done ✓
blocked ✗
in progress …
blocked ✗
in progress …
blocked ✗
Write the demo —
done ✓
blocked ✗
in progress …
blocked ✗
in progress …
in progress …
Each row picks one of three states from two nested conditionals, all in plain Markdown — no component, no ternary, no JavaScript.
Live filtering — search in pure Markdown
@loop … where filters a list, and because the predicate reads a :state value, the loop re-filters live as you type. :bind is the input bound two-way to that state. Type below and watch the list narrow — no event handlers, no JavaScript:
— $
Aurora Lamp — $49
Briza Fan — $39
Cove Speaker — $89
Dune Mug — $12
Ember Kettle — $64
The predicate whitelist is compile-time validated — item fields, declared state, numbers, and strings only. An item-only predicate (say where p.price < 50) would instead filter at build time and ship zero JavaScript.
…and an editable cart
A :button inside a loop can act on its own row. Add to cart carries the row into another list; Remove drops a line — a whole add/remove flow with no JavaScript:
— $
Section-scoped state
Two sections can each own a state value named tally without colliding. Buttons resolve to the nearest scope:
Left section
The left tally is 0.
Right section
The right tally is 10.
Static pages like the docs stay runtime-free.