how this site fakes a backend

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

ToolVersion / pathRole on this site
Datastarv1.0.3 · vendor/datastar.jsThe subject itself: hypermedia UI — backend patches elements/signals over SSE, frontend reactivity via data-*.
fetch-shim registryshared.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/datav1.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).
BroadcastChannelplatformCross-window transport: replica sync, presence heartbeats, cursor positions. Ephemeral by nature — which is the lesson.
CodeMirror 55.65.16 · vendor/codemirror/The tour editors (gruvbox-dark), with live signal values as inlay-hint bookmarks.
js-beautify1.15.4 · vendor/js-beautify/Format button (HTML + JS modes), and the pipeline that bakes formatted defaults.
JetBrains Mono5.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 deltasOrdered commit log fan-out (validated; ours isn't)
Outbox + replay on reconnectDurable outbox, idempotent commits
Event ledgerDomain event rows, written atomically
Rooms (filtering)Scopes (authorization — the piece you write)
Signal patches from store readsReactive queries / live snapshots
Presence + cursors, explicitly non-storeExplicitly 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.