About: a fullstack demo with no stack
Every interactive demo on this site runs against a backend that doesn't
exist. There is no server process, no database, no deploy — just static
files. The pages implement the backend half of Datastar patterns
in the browser (fetch interception, SSE streams, collections,
cross-tab sync) so each pattern can be read, edited, and broken live.
Everything below is vendored under vendor/;
the site builds with nothing (python3 -m http.server)
and deploys as static files.
The kit
| Tool | Version / path | Role on this site |
|---|---|---|
| Datastar | v1.0.3 · vendor/datastar.js | The subject itself: hypermedia UI — backend patches elements/signals over SSE, frontend reactivity via data-*. |
| fetch-shim registry | shared.js (DS.handle) | The backend for every tour page: declare-handlers-per-endpoint, answered in-page (fetch shim + true streams). Handler tabs compile to it. |
| @mswjs/data | v1.1.8 ex-GitHub · vendor/msw-data/ | Real models for the CQRS board: schema-checked scores collection, ops, change hooks, cross-tab sync(). Released on GitHub only — vendored from source (see VENDOR.md). |
| BroadcastChannel | platform | Cross-window transport: replica sync, presence heartbeats, cursor positions. Ephemeral by nature — which is the lesson. |
| CodeMirror 5 | 5.65.16 · vendor/codemirror/ | The tour editors (gruvbox-dark), with live signal values as inlay-hint bookmarks. |
| js-beautify | 1.15.4 · vendor/js-beautify/ | Format button (HTML + JS modes), and the pipeline that bakes formatted defaults. |
| JetBrains Mono | 5.3.0 · vendor/fonts/ | Editor + code typeface. |
The SDK that wants to exist
Building these pages kept reinventing the same five pieces. Factored out, they'd be a small browser kit for Datastar + CQRS + SSE — enough to demonstrate fullstack concepts (commands, read models, streams, presence) with zero infrastructure. The recurring shape:
// sketch, not shipped code — the pattern every page converged on
Store.commit(cmd) // mutate + notify + broadcast (local command)
Store.merge(cmd) // mutate + notify, never rebroadcast (remote command)
Store.subscribe(fn) // re-read + patch on every change (read model)
patch(`<div data-on:evt__window="...">`) // the bridge: JS can't write $signals,
// so a mounted div turns events into patches
Plus the honesty rules that survived contact with users: tab sources are the running code (text/plain blocks, no escaping games), edits re-apply live, broken tabs fail visibly without killing the demo, and subscriptions are owner-scoped so navigation never leaks listeners.
Next: durable state via sqlite-wasm
Evaluated, not yet vendored. The official sqlite3 WASM build would give each tab a durable relational store: per-origin persistence via OPFS, SQL read models instead of hand-rolled maps, and the worker-based API keeps queries off the UI thread. What changes if it lands: the board survives reloads, presence stays ephemeral by contrast, and the "fake backend" gets one step harder to distinguish from a real one.
Costs, honestly: roughly a megabyte of wasm+JS, an async worker API everywhere state is touched today, and secure-context-only (already true here — localhost and Pages both qualify). Verdict: the natural next modeling step after collections; waiting for a demo that needs durability before paying the megabyte.
The real version of this architecture
Everything above is a fake of something real: syncular — offline-first SQL sync with local SQLite per client and a server-authoritative commit log. Our demos mirror its shape with no server:
| Here (faked) | There (real) |
|---|---|
Per-window replica (Store, collections) | Local SQLite per client |
| Broadcast deltas | Ordered commit log fan-out (validated; ours isn't) |
| Outbox + replay on reconnect | Durable outbox, idempotent commits |
| Event ledger | Domain event rows, written atomically |
| Rooms (filtering) | Scopes (authorization — the piece you write) |
| Signal patches from store reads | Reactive queries / live snapshots |
| Presence + cursors, explicitly non-store | Explicitly out of scope there too — "frame-by-frame multiplayer belongs in netcode" |
Adopting it would cost the premise: syncular has no peer-to-peer mode, so the demos would need a real server. Until then it serves as the reference — and the vocabulary (commit log, scopes, outbox, domain events) is already leaking into the steps above, which is exactly the point.