I wanted to see where current models stand when pushed past standard web boilerplate and into systems software. So I set out to build urlfs.
The ask is simple, if slightly wierd: an entire stateful operating environment that lives inside a browser address bar.
A WebAssembly binary, a virtual filesystem, environment variables, command-line arguments, and standard I/O, all packed into a single client-side URL. You run an wasm executable in your browser, modify files, and the address bar updates in real time. Copy the link, send it to someone, and they boot up your exact machine state. Zero backend, zero server state.
To make this work without cheating, it needed real systems plumbing:
- A custom WASI Preview 1 runtime running inside a Web Worker.
- A binary wire format, compressed with raw DEFLATE (
deflate-raw) into a base64url hash fragment. - An in-memory WebAssembly bytecode assembler capable of emitting working modules on the fly.
- A BusyBox simulation featuring 30 standalone applets (
cat,cp,grep,head,tail,stat,df,free,ps, and an interactivesh) implemented directly in raw WASM instructions.
I built the entire project with Gemini 3.8 Flash High using Antigravity.
Here is what I learned.
⇒ One-Shot Structural Competence
Going in, I anticipated the usual failure modes that have plagued LLM-assisted programming: confident hallucinations of function names, sloppy alignment and context drift as the codebase crossed 3,000 lines.
That is not what happened. The model showed an amazing degree of competence.
More strikingly, it wrote the bytecode emitter and assembled 30 BusyBox applets directly into binary WASM without relying on an external compiler toolchain like Emscripten or Rust. It understood WebAssembly's stack machine semantics, local variable indices, and structured control flow blocks (block, loop, br_if) with virtually zero architectural hallucinations.
Surprisingly, the system was synthesized with speed and shocking coherence.
⇒ Verification is the New Bottleneck
When the cost of producing syntactically plausible, complex systems code drops to near zero, the developer's role fundamentally inverts.
You no longer spend your day writing implementations. But you also cannot simply eyeball 3,000 lines of generated code or trust that a binary handles edge cases cleanly across all browsers.
The developer's job shifts entirely to verification.
Nearly all the human effort on urlfs went into building the harness:
- Wire-format fuzzing (
test_wire_format.js): Verifying roundtrip serialization, bit-level integrity, and raw DEFLATE boundary conditions. - Bytecode validation (
test_all_demos.js): Running all 30 BusyBox applets and demo binaries through the WASI runtime in Node to assert standard stream outputs. - End-to-End browser automation (
test_in_chrome.js): Spawning headless Chrome over the DevTools Protocol to verify that the Web Worker, VFS synchronization, terminal UI, and URL hash updates didn't race or desync under real DOM conditions.
In an AI-dominated workflow, unverified code is just liability. If you haven't written the automated harness to rigorously falsify the model's output, you haven't actually built software, you've just accumulated debt.
⇒ The Gating Factor
There is a natural progression in how we interact with computing abstractions. Previously, we moved from writing raw assembly to higher-level compiled languages, the compiler took over register allocation and instruction scheduling, and we adjusted our mental models to interface design and algorithmic complexity.
Working with the current models on urlfs felt like another step across that boundary. The model doesn't just autocomplete boilerplate; it holds large, complex system interfaces in working memory and generates functional implementations across multiple layers of abstraction.
The bottleneck is no longer synthesis. The bottleneck is our ability to specify constraints and build deterministic verification loops fast enough to keep up with the generator.