rewritable

reWritable: Software that knows how to change itself

When I built clive, the core insight was deceptively simple: don't give the agent a list of tools. Give it an environment.An API is a call-response primitive. You invoke it, it returns something, the state lives somewhere else. An environment is a thing you inhabit. You enter it, act inside it, leave it different than you found it. The terminal has always been an environment. Clive just puts an LLM in it. I've been thinking about what that insight means outside the terminal. And I think it points somewhere surprising: the browser tab.

The web was supposed to be read/write

Tim Berners-Lee designed the browser as an editor. The first browser — WorldWideWeb — could create and modify pages, not just read them. The read/write web was the plan. Then the web became a distribution medium. Apps live on servers. Citizens consume them. If you want to change something, you file a ticket. If you want to build something, you hire a developer. Open source didn't fully fix this. The code is visible, but the gap between "can read" and "can change" is still enormous. Most people who use software cannot modify it. Most people who could modify it still can't deploy it.

The result: a web full of knowledge, locked inside interfaces you don't own, running on servers you don't control, maintained by teams you can't reach.

What if the file was the deployment unit?

HTML is the most widely deployed runtime format in history. Every device with a browser can run it. No install. No account. No server. You just open the file. Simon Willison has been building single-file HTML tools for two years — over 150 of them. A PyPI changelog viewer. A Bluesky thread explorer. An OCR tool that runs entirely in the browser. All of them: one .html file, drag to desktop, open, done. His observation: a few hundred lines of HTML is the most deployable format that exists. Any good LLM can read it, understand it, and rewrite it from scratch in minutes. That last sentence is the one that opened something for me.

What if the file could rewrite itself?

The architecture is straightforward in hindsight:

one .html file
↓
on first open: the LLM generates the app, stores it in localStorage
↓
on every open after: localStorage loads into the browser via document.write
↓
⌘K: the LLM receives the entire current source, rewrites it, stores the new version
↓
the file has modified itself

The file on disk is a 20-line seed — an immutable bootstrap. Like gate.py in clive's self-modification pipeline, it never changes. It just loads whatever is in localStorage.

Everything else — the UI, the logic, the data, the styles — lives in localStorage['docuapp_src']. The agent doesn't modify data inside an app. It rewrites the app itself. This is not the same thing as configuring an app, or personalising a dashboard, or changing settings. It's a different ontology entirely. The app is not a fixed artifact with variable content. The app is what the agent has made so far. Source, runtime, and editor are the same thing.

The null origin accident

Here's something that sounds like a problem but isn't. When you open local HTML files via file://, all of them share the same origin: null. That means every .html file you open locally shares the same localStorage namespace.

The first reaction is: bug. Documents will stomp on each other.

The second reaction — once you sit with it — is: this is a local message bus.

budget.html     → writes localStorage['budget_data']
tracker.html    → writes localStorage['tracker_data']
dashboard.html  → reads both, renders a unified view

No server. No protocol. No WebSockets. The browser fires window.addEventListener('storage', ...) when another tab changes localStorage. Documents can react to each other in real time.

A folder of .html files is secretly a distributed application. The file system is the network. The browser is the runtime and the message bus.

This behaviour is consistent across modern browsers but is browser-dependent enough to treat as a hackable substrate rather than a standards-backed guarantee. It's a foundation worth building on, not a foundation worth shipping to production without a fallback.

What is actually new here

Single-file apps existed. Self-modifying systems existed. Local-first apps existed. Browser-based code generation existed. What is new: LLMs make the single-file artifact editable at the level of intention, not syntax. Before, modifying a program required understanding the program. You had to know which line to change, what the consequences would be, how the parts connected. The artifact was opaque to its user.

Now, the artifact can receive a sentence — "make the text bigger," "add a priority field," "ändere die Begrüßung auf Gemeinde Tulln" — and rewrite itself accordingly. The user's intent is the interface. The source code is an implementation detail the user never sees. That's not a quantitative improvement on existing tools. It's a different relationship between people and software.

reWritAble

The name came out of thinking about what this actually is.

re — it does it again. The agent loop. Iteration. Self-modification over time.
write — not read. Not consume. Author. The verb Berners-Lee intended.
able — a property of the file itself. Not a permission the OS grants you. Something it is.

The download is the fork

This reframes what a download means. Traditionally: a download is a frozen copy of what the developer made.

reWritable: a download is a starting point the user can evolve. The re-write-able runtime ships inside the file. The user doesn't install anything, doesn't sign up for anything, doesn't need a separate tool. The modification layer is baked in. Open source has always been theoretically accessible — the code is there, anyone can modify it. But practically, the gap between "can read" and "can change" required years of skill.

reWritable closes that gap for a specific class of software: lightweight, local-first tools and artifacts — the kind of thing that used to live in a spreadsheet, or a Word document, or a shared folder, or a Notion page. Not a replacement for all software. A radical expansion of what can count as deployable software for individuals and small organisations. The implementation cost for software at this scale is collapsing. That doesn't make thinking obsolete — it makes thinking the job.

What changed and what didn't

The LLM did not change the underlying economics of all software. Complex systems still require engineering, judgment, and maintenance. That hasn't changed. What changed at the small end: the translation layer between intent and implementation has become cheap enough to ignore for a large class of internal tools, local utilities, and single-purpose artifacts. For those use cases, describing what you want is now most of the work.

A few real constraints worth naming:

  • localStorage has limits (~5–10MB depending on browser). The spec addresses this with a two-tier model: localStorage for the app source, IndexedDB for larger data — giving each layer the right tool.
  • Self-rewriting accumulates drift. After many modifications, the source can become bloated, contradictory, or fragile. The right fix is periodic regeneration from a compact spec — rewrite from scratch rather than patching indefinitely.
  • The API dependency is real. The file works offline, but the agent call requires a network. Roman answers questions without internet; Roman rewrites himself with it.
  • Rollback matters. The runtime keeps ten levels of undo. For anything that matters beyond that, version the file in git — it's text, it diffs cleanly.

The connection to clive

Clive's thesis: the terminal is an agent habitat because it's observable, stateful, and persistent. The agent reads the screen, types keystrokes, watches what happens, repeats.

Re-write-able is the same thesis in the browser.

clive:         read screen → type → watch → repeat
re-write-able: read outerHTML → generate → document.write → repeat

The browser tab is the habitat. localStorage is the persistent state. document.documentElement.outerHTML is the screen capture. The agent lives in the tab.

The difference: in clive, the agent drives programs. In re-write-able, the program is what the agent has made so far. There is no separation between the tool and its history of modification. Every rewrite is a new version of the artifact. The artifact has memory.

Artifact. Inhabitant. Memory. Those three things together are what make this different from an app builder in the browser.

What's next

The two most natural extensions are already implied by the architecture. The localStorage bus makes cross-document agents possible — a set of re-writeable files that read and write each other, forming a local application without a server. And the file-is-text property makes versioning trivial: every rewrite is a diff, every export is a snapshot, git already works. Both of these are directions, not features. The more interesting question is what people build when the cost of building a local-first tool is a sentence. The web was supposed to be read/write. For most people, for most of its history, it wasn't. One file. One sentence. One rewrite at a time.

Source and spec: github.com/ikangai/rewritable
The direct ancestor: github.com/ikangai/clive

Unlock the Future of Business with AI

Dive into our immersive workshops and equip your team with the tools and knowledge to lead in the AI era.

Scroll to top