The Web Browser Is an Operating System in Denial

Open your task manager and look at the browser. A dozen processes, each one sandboxed, each one isolated from the others, each one running untrusted code pulled off the network seconds ago, each one asking you for permission before it touches your camera or your location, each one with its own private slice of storage. That is an operating system, and it is running inside another operating system that was supposed to do all of this and did not.

A huge fraction of the modern browser exists to provide things the OS underneath it failed to deliver: real sandboxing, per-origin isolation, permission prompts, a safe way to run untrusted code, and a distribution channel that routes around the native app model. The browser did not grow this machinery for fun. It grew it because nobody else would.

Calling the browser bloated would be cheap and wrong. The browser is one of the great engineering achievements of the era. The teams who built Chromium and Firefox and WebKit took a genuinely hostile problem, running arbitrary code from strangers safely on a machine full of your secrets, and solved large parts of it on top of an OS that gave them almost nothing to work with. They had to rebuild an OS to do it, and a better OS underneath would have meant they did not.

What the browser had to reinvent

Every item below is a primitive an operating system is supposed to own, reimplemented inside an application because the application could not get it from below.

Per-site process isolation. Modern browsers put different sites in different OS processes so a bug in one site’s renderer cannot read another site’s memory, and a compromised renderer is trapped behind a sandbox with almost no authority. This site isolation is excellent work, and it is the operating system’s job. The browser uses the OS’s own process and memory isolation as raw material and builds a second, finer-grained model on top, because the OS’s notion of a security boundary is “a user account,” far too coarse to put between two tabs.

The permission model. Camera, microphone, location, notifications, clipboard. The browser prompts you, remembers your answer per site, lets you revoke it, and scopes the grant to one origin. That is a capability system with a consent UI, and it is better than what the desktop OS historically offered, which for a native app was usually nothing: an app that wanted your webcam just opened it. The browser built a real permission layer because the platform it sits on had none that worked per application, let alone per origin.

A sandboxed execution runtime. JavaScript engines and WebAssembly run code you did not write, review, or install, without that code owning your machine. An entire discipline of just-in-time hardening, memory-safe execution, and capability-free-by-default APIs exists so that visiting a URL is not the same as running an .exe. The native model is the opposite: downloading and running a binary hands it your full ambient authority and hopes for the best. The web runtime is the safe execution environment the OS never provided for native code.

Storage abstractions. Cookies, localStorage, IndexedDB, the Cache API, the origin-private file system. Each is a per-origin, quota-bounded, isolated store, because a site must persist data without reading every other site’s data and without touching your real files. That is a filesystem with per-principal partitioning and no global root. The browser built it because the OS filesystem is one global tree where, by default, any code you run can read anything you can read.

A distribution channel. The quiet one, and maybe the most important. You use software in the browser because typing a URL is safe and installing a program is not. No installer, no sudo, no “this app wants to make changes to your device,” no supply-chain ritual. The web became the dominant way to ship software precisely because the native install model was dangerous enough that an entire industry routed around it. The browser is a software distribution system that beat the native app model on safety, and won.

Process isolation, a permission model, a safe runtime, partitioned storage, a safe distribution channel: a list of operating system responsibilities, dressed up as browser features. The browser is an OS in denial about being an OS.

Why this happened, charitably

This was not a mistake by the OS vendors, exactly. It followed from a foundational decision made decades ago that everything else inherited: the unit of trust on a desktop OS is the user, and a process runs with the user’s full ambient authority. Once that is the floor, you cannot safely run untrusted code, because “running” means “running as you, with all your power.” And you cannot safely distribute software, because installing means handing that power to a stranger’s binary.

The web could not live with that. Its entire premise is untrusted code from strangers, by the millions, executed on sight. So the browser had no choice. It could not wait for the OS to grow a capability model and per-origin isolation and a safe runtime, so it built them itself, inside one process tree, against an OS that kept insisting the right granularity of trust was your login account. The criticism lands on the gap the browser was forced to fill, not on the browser.

When the OS provides the primitives natively

Now change the floor. Suppose the operating system does not run apps with your ambient authority. An app starts holding nothing and only ever reaches what it was explicitly handed. Isolation is the default, a sandbox is just “an app you did not hand the real roots to,” and distribution is safe because installing grants no authority. This is what Cathedral, the OS I am building, is for.

In that world, a lot of the browser’s machinery stops being load-bearing.

Per-site process isolation as a bespoke layer becomes redundant, because the OS already isolates principals at the right granularity and an origin can simply be a principal. In Cathedral a web origin like https://app.example.com is a first-class principal in the capability system, holding and granted capabilities exactly like a native app. The same-origin boundary the browser fought to enforce becomes a principal boundary the OS already understands. The OS’s model is finally fine-grained enough to use directly.

The permission model collapses into the OS’s one consent surface. A web permission prompt and a native one are the same gesture routed through the same trusted path, granting a capability into the same authority graph. “What can this thing do,” asked of a website, is the identical query you ask of a native app, with the identical answer surface and one-click revoke. The web’s filesystem-access API becomes the OS file picker minting a narrow capability, the same mint a native app gets. There is no parallel permission universe to keep reconciled.

Storage stops being a reinvention. Per-origin partitioned storage is what the OS filesystem already does for every principal: each app gets its own realm, its own private root, reaching nothing else by default. An origin is a principal, so an origin gets a realm. IndexedDB and the origin-private file system were a partitioned filesystem built because the real one was a single global tree; when the real one is already partitioned per principal with no global root, the abstraction they compensated for is gone.

Safe distribution stops being the browser’s special trick. Installing a native Cathedral app grants it no authority, so the ambient power that made native install dangerous is not there to hand over. The web won distribution on safety, and once native distribution is safe, the URL’s monopoly on “I can run this without fear” ends.

Be precise about what survives

It would be a lie to say the browser vanishes.

The browser is also a genuine document and application platform, and that part does not disappear. The rendering engine is real, hard, irreplaceable work: HTML and CSS layout, the cascade, text shaping, the painting and compositing pipeline, decades of accumulated correctness about how a page is supposed to look. None of that is an OS primitive in disguise. It is the actual web platform, and it stays.

The web as a content and application model stays too. The DOM, the styling system, the layout model, the enormous corpus of existing sites and web apps, the entire developer ecosystem: that is the real value the browser delivers, and native capabilities do not make it redundant. If anything they make it cleaner, because a web app can now hold native capabilities under the same ceilings as native code instead of being trapped in a sandbox that can only reach the OS through the browser’s narrow re-exposed surface.

So the precise claim. The isolation, permission, safe-runtime, partitioned-storage, and safe-distribution layers, the parts of the browser that are really OS primitives reimplemented inside it, become largely redundant when the OS provides those primitives natively. The rendering engine and the web platform, the parts that are actually a document and application system, remain and arguably get better. The browser stops having to be an operating system. It gets to go back to being a web platform, the thing it was good at before it grew a kernel inside itself to survive.

There is a real risk of overclaiming. A browser-class device still needs a renderer, still needs to speak HTTP and TLS, still needs to authenticate origins, and the long tail of sites you visit once may never become full principals. The legacy browser may have to stick around as a sandboxed compatibility runtime for the web that predates any of this. But an entire half of the browser exists only because the OS abdicated, and when the OS stops abdicating, that half has nowhere left to hide. The browser itself does not die.

The mental model: the browser is a second operating system that the first one forced into existence, and a real OS underneath lets the browser put the kernel down and go back to rendering the web.