A live app, in one Markdown file
Everything on this page — the prose, the fetched list, the badges, the form, the counter — is a single .wd file. No components. No JSX. No build config. Watch where JavaScript actually enters.
Static until proven reactive
This whole section is plain Markdown. The list below is unrolled at build time from a JSON file — it renders into HTML with no runtime at all:
- —
- —
- —
Fetched data, looped, with nested conditions
:fetch pulls JSON over the network into reactive state — from a static file here, or any API. Until it lands, the page shows a fallback. Each row then decides its own badge from nested conditionals, in plain Markdown:
blocked
shipped ✓
in progress
Loading the roadmap…
Loading the roadmap…
No ternaries, no .map(), no framework — the outer :if checks blocked, the inner one checks shipped, per row, and both stay reactive.
A counter that survives reload
:state … persist keeps this in localStorage, and :computed derives from it. Star a few, reload the page, and it holds:
You are watching 0 item(s).
Nice — you are tracking the whole near-term roadmap.
A form that talks to a real server
This form posts to a live serverless function and shows the reply. With JavaScript it is a fetch; without it, the exact same markup is a native POST — Darkmown adapts to your backend instead of owning one:
The server got it and answered at .
Your reply will appear here.
Your reply will appear here.
Something went wrong:
That was one file. Static prose, build-time loops, fetched data, nested conditionals, persistent state, computed values, and a server round-trip — and the only JavaScript on the page is the shared runtime Darkmown loads for you. Read the docs or deploy your own.