- claim the lang42 prefix; iteration 42 story (readiness: ready), approved spec, and the 11-task implementation plan - board: pending row for 42; graph: node 42 with green edges (11, 24) - graph: porch track section added (same sweep) - parity studies that motivated 42: alacritty, tmux, zen-browser under docs/plan/exploration/ — staged path, gap lists, refused routes Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
4.9 KiB
Zen Browser parity — what a browser-class application actually asks of a language
Source: .dev/reference/zen-browser/
(shallow clone of zen-browser/desktop, surveyed 2026-09-01). Third study in the
series after alacritty and
tmux — and the one whose answer is different in
kind, which is why it is worth having.
What Zen actually is (measured)
Zen is not a browser codebase. It is a Firefox overlay: surfer.json pins
product: firefox, version: 154.0.1, npm run download fetches the Firefox
source into engine/ at build time, and the repo contributes 256 patch
files plus a 33 MB src/ tree that is copied over it — ~246,000 lines
counting JS/MJS/CSS/XHTML/patches (616 .js files, 568 Fluent localization
files, 48 CSS). There is no rendering, layout, JS-engine, or networking code
in the repository at all; Gecko (tens of millions of lines of C++/Rust)
arrives as a downloaded dependency and is built with Mozilla's own mach.
Zen's value-add lives in src/zen/: workspaces ("spaces"), split view,
compact mode, glance, folders, session store, sync — all UI composition and
state, written in JavaScript because the engine ships a JavaScript host and
Zen's code runs inside it. The engine is also the app platform.
The lesson, stated plainly
Nobody — including a successful, well-staffed browser project — writes a browser. They skin an engine. So "mature the language until it can build an application such as this" resolves to three different questions, and only one of them is real work for writeonce:
- Build the engine in
.wo? Not a maturity path, a decades-long refusal. The gap list it produces ("general FFI, C++ interop, a GPU pipeline, a JS VM…") is the alacritty study's stage-E fork multiplied by a thousand, with no intermediate shippable stage. Rejected as a driving workload — it cannot drive, only sink. - Embed an engine (CEF/WebKitGTK) behind FFI? The heaviest possible FFI consumer. Same fork as alacritty item 7, and this study deliberately does not promote it: an embedded engine's API surface is enormous and unstable, the worst first FFI customer imaginable.
- Drive an engine out-of-process. Chromium and Firefox both expose a
remote-debugging protocol (CDP; Firefox now speaks it too) over a local
socket or a stdio pipe. A writeonce program that spawns a browser, connects,
and drives it — kiosk shells, scrapers, site-acceptance drivers of the kind
site-accept.shfakes with curl today — is the browser-class workload that is actually reachable, and it is exactly the actor/protocol shape the runtime is built around. This is Playwright's architecture, minus the Node.js.
What route 3 needs — mostly the existing list, one genuinely new gap
- Bounded subprocess with stdio transport — spawning the browser with a pipe transport is the third consumer of iteration 28's named gap (after the alacritty and tmux studies' PTY stages; this one does not even need a PTY).
net.connect— iteration 38, already named, for the debugging socket.- NEW — WebSocket CLIENT. CDP speaks WebSocket; iteration 24 landed the
server side (
ws_accept, frames) but nothing performs an outbound upgrade handshake. Small — the frame code is the hard half and already exists. - JSON both ways — exists. Actor-per-session/per-tab supervision, timeouts
(
time.after), graceful teardown — all landed in iteration 24.
Notably absent: nothing graphical, no terminfo, no termios, no fd passing. Route 3 is closer than the tmux stage.
What Zen's own feature layer says about writeonce
Zen's ~250k-line overlay is session stores, workspace state, sync, and
declarative UI — in writeonce terms: @table rows (durable by declaration
since databasev2 2), and wo-html components. The project's existing bet —
that the browser is the client and the application lives server-side in
porch — already covers the useful half of what Zen builds. The other half of
Zen's lesson is about hosting: Gecko wins as a platform because it embeds a
scripting language with capability boundaries, which is iteration 28's
skillhost direction (writeonce as the confined host, not the confined guest).
Verdict for the maturity path
The browser study adds one builtin-sized gap (WebSocket client) and
one workload to the staged path from the alacritty study — call it
stage C′, the browser driver, parallel to stage C (it needs subprocess +
net.connect + ws-client, none of stage C's tty machinery). Proof when it
lands: replace a curl leg of site-accept.sh with a .wo driver that opens
writeonce.de in a real browser, asserts the rendered chapter list, and tears
the browser down cleanly — the site gate exercising the language's own
browser-automation story end to end. Engine-building and engine-embedding
stay refused, by name, with this study as the reason.