WEFT OS — Post 1 of 10
There is a file on my machine called system-ui.html.
Right now it’s just a file.
The idea behind WEFT OS is that it shouldn’t stay “just a file” for long.
The idea is that when a shell renderer loads that HTML document, you don’t get a web page.
You get a desktop.
A taskbar. A launcher. Notifications. Window chrome. The pieces of a desktop environment — not rendered by a web app, but rendered as a document.
If that sentence sounds either obvious or insane, that’s normal. It depends on which decade of computing you grew up in, and which scars you carry.
If you remember Firefox OS or Ubuntu Touch, you might be nodding.
If you’ve never heard of either, you might be thinking: “so… Electron?”
It’s not Electron.
It’s not “a browser skin”.
It’s an attempt to treat the web platform as a systems primitive.
This is the opening post of a 10-part series about WEFT OS — what it is, what it’s trying to prove, what is genuinely hard about it, and what a desktop looks like when you take HTML and CSS seriously as OS UI.
Before we go any further, I want to be clear about what this series is and isn’t.
It isn’t a launch announcement.
It isn’t a product page.
It isn’t a “follow along as I build in public” devlog.
At least not in the way devlogs usually work.
It’s something else:
- a sustained argument
- told through a technical system
- about what happens if you treat web standards as first-class UI technology
Some of the writing will be speculative in the only responsible way speculation is allowed in engineering:
- “this is the model I’m trying to build”
- “this is why I think it’s coherent”
- “this is where it might fail”
When something is not yet proven by implementation, I’m going to say so.
Because the fastest way to kill a project like this is to pretend unknowns are solved.
🔗What “the desktop is a document” is trying to invert
Most desktop UI stacks are built like a pyramid.
At the bottom you have:
- a compositor
- a set of surfaces
- a widget toolkit
- and then an application framework
If you’re on Linux you might recognize the ecosystem by smell:
- Wayland or X11
- then some compositor/shell combination
- then GTK/Qt
If you’re on Windows or macOS the details change, but the shape doesn’t.
The “shell” is usually a special thing built with special primitives that apps can’t use.
Then the apps are built with different primitives.
And over time you get a system where:
- the shell is one world
- apps are another world
- and the seam between the two gets weirder every year
WEFT is trying to invert that.
It’s trying to say:
- the shell is a document
- apps are documents
- the difference is not the UI language
- the difference is authority
That inversion is the reason I keep repeating “document” instead of “web UI.”
Because “web UI” sounds like “website.”
And “website” implies a set of assumptions that don’t survive contact with an OS.
🔗What this is not: a desktop inside a single browser surface
The easiest misconception to correct is also the most important.
People hear “desktop is HTML” and imagine:
- one big web surface
- and everything is inside it
That architecture exists.
It’s easy to build.
It also collapses a lot of boundaries:
- apps become iframes
- input becomes weird
- crash recovery becomes a joke
- security becomes “trust the UI process”
WEFT is explicitly trying not to do that.
The “desktop document” is the shell.
It renders chrome.
It renders global UI.
But application content is not in its DOM.
Application content is a separate surface, owned by the app, composed by the compositor.
If you only take one idea away from this post, it should be that separation.
Because it’s the difference between:
- using web tech for UI
and:
- turning the OS into a single privileged web process
🔗“So… Electron?” (why that question is reasonable, and why it’s wrong)
I understand the Electron reaction.
It’s the obvious reference point.
Electron taught a whole generation that:
- you can build desktop UI with web tech
It also taught a whole generation that:
- bundling a browser is expensive
- the process model gets weird
- memory use becomes a punchline
- and the app is still not really a first-class system citizen
When someone says “this is an Electron app”, they’re not insulting HTML.
They’re pointing at a pattern:
- a web runtime bolted onto a native app
WEFT is not that pattern.
WEFT is an attempt to build an OS where web rendering is not a bolt-on.
It’s the shell renderer.
And because the shell is not the compositor, and apps are not inside the shell, the system is not “a browser pretending to be a desktop.”
That distinction matters.
It’s also easy to claim and hard to earn.
🔗Why this idea keeps coming back
There are two reasons this idea keeps resurfacing:
- The web is the most widely deployed UI technology in history.
- The web’s layout and compositing model is unusually expressive.
Every few years, someone looks at that and asks:
- why are we still re-implementing UI systems from scratch?
Firefox OS asked that.
So did various “HTML-based shell” experiments.
So did entire application platforms.
The reason it keeps failing is not because the question is silly.
It’s because the answer has to be disciplined.
There’s another reason it keeps coming back, and it has less to do with technical elegance than with culture.
The web is one of the only UI languages on earth that already has a truly global labor pool.
Millions of people know enough HTML and CSS to build something visible.
That matters.
It matters because platforms are never only about rendering.
They’re also about who gets to participate.
Every time someone proposes the web as a system UI substrate, part of what they are really proposing is:
- a lower barrier to building software that looks native to the platform
That doesn’t solve performance.
It doesn’t solve architecture.
It doesn’t solve security.
But it does explain why the idea refuses to die.
People keep returning to it because a shared UI language has social power, not just technical convenience.
You can’t just “use HTML.”
You have to build a system where:
- performance constraints are design constraints
- input is correct at the compositor boundary
- authority doesn’t leak into the UI runtime
- and crash recovery is architected, not hoped for
🔗A slightly more concrete shell picture
The earlier DOM snippet was intentionally simple.
Here’s the same idea, but closer to how shell UI actually feels: a few components that exist all the time, and a set of window entries that come and go.
<weft-desktop>
<weft-wallpaper></weft-wallpaper>
<weft-top-bar>
<weft-clock></weft-clock>
<weft-status-tray></weft-status-tray>
</weft-top-bar>
<weft-taskbar>
<weft-launcher-button></weft-launcher-button>
<weft-task-list></weft-task-list>
</weft-taskbar>
<weft-notification-center></weft-notification-center>
<weft-window app-id="com.example.notes"></weft-window>
<weft-window app-id="com.example.browser"></weft-window>
</weft-desktop>
Again: illustrative.
The point is not that these exact tags exist today.
The point is the mental model:
- the shell is a UI tree
- expressed as DOM
- styled and animated with CSS
If you’re a web developer, this should feel oddly familiar.
If you’re a systems developer, it should feel suspicious.
Both instincts are correct.
🔗Why 2026 is different (without pretending it’s easy)
If this was 2013, this post would be irresponsible.
Because in 2013 you didn’t have a clean way to pair:
- a web-rendered UI
with:
- a capability-oriented app runtime
You had JavaScript.
You had sandboxes that were mostly “best effort”.
You had permission prompts.
Today the ecosystem looks different:
- WebAssembly exists as a portable, sandboxable target.
- WASI exists as a direction for capability-shaped interfaces.
- Wayland is the default direction for Linux display.
- Rust is a normal systems language.
None of those make the problem easy.
But they make it coherent to try.
🔗What is genuinely hard (and why I’m not hiding it)
There are at least three hard problems that a “desktop as a document” architecture cannot dodge.
🔗1) The boundary between shell and compositor
If the shell is a document, it will want to behave like a shell.
It will want to create windows, move them, resize them, manage focus.
If you let the shell become authoritative over those, you lose the contract.
So the boundary must be explicit.
In WEFT OS, that boundary is specified as a WEFT-specific shell protocol between weft-compositor and servo-shell.
That protocol design exists today, but it is explicitly not implemented yet.
🔗2) The boundary between app logic and UI
If apps are “two things” (a Wasm core and an HTML UI), the channel between them becomes the heart of the system.
If it’s too loose, authority leaks.
If it’s too chatty, performance dies.
If it’s not observable, debugging becomes superstition.
The current WEFT direction is a brokered message channel owned by weft-appd.
That’s a design direction today, not a shipped implementation.
🔗3) Servo correctness as a first-order dependency
If the shell is rendered by a web engine, then web engine correctness is no longer “a browser bug.”
It is a system UI bug.
That changes the responsibility model.
It implies upstream work, verification, and an uncomfortable amount of rigor.
None of these problems are optional.
This series exists to talk about them as problems you can name, not problems you hand-wave.
🔗What “the desktop is a document” actually means
Let me be concrete, because the abstraction is slippery.
In WEFT OS, the system shell is intended to be a document loaded by a Servo-based shell process (a Wayland client of the compositor).
There is already a weft-servo-shell binary in the repo that:
- connects to a Wayland compositor
- locates
system-ui.html
But the Servo embedding entry point currently errors intentionally: Servo embedding is not yet implemented.
So the line between “this is the model” and “this exists” matters here.
The model looks like this:
- Servo parses HTML into a DOM.
- Servo computes layout.
- Servo paints.
- Servo animates.
The difference is what it’s painting.
Not a website.
The shell.
If you imagine the DOM of the shell, it looks more like a UI tree than a web page:
<weft-desktop>
<weft-wallpaper></weft-wallpaper>
<weft-taskbar></weft-taskbar>
<weft-launcher hidden></weft-launcher>
<weft-notification-center></weft-notification-center>
<weft-window app-id="com.example.notes"></weft-window>
<weft-window app-id="com.example.browser"></weft-window>
</weft-desktop>
That snippet is illustrative, not a promise of current implementation.
But it captures the idea: the system UI is expressed as DOM and rendered with CSS.
And that immediately creates the first real objection:
- “So the app is inside
<weft-window>?”
No. That’s the trap.
In WEFT, application pixels are not embedded into the shell’s DOM tree.
That boundary is the difference between “a desktop as a document” and “a desktop as a single web surface pretending to be an OS”.
The shell draws chrome.
Applications draw their own content.
Those two meet on the screen in the compositor, not in the DOM.
If you’ve never built anything close to a window system, this can sound like pedantry.
So here’s the practical test for whether the boundary is real.
When the app repaints, the shell shouldn’t need to re-render anything.
When the shell animates a panel, the app shouldn’t need to wake up.
When the shell crashes, the app surface shouldn’t evaporate into nothingness.
And when an app crashes, the shell should remain calm enough to do the most important thing an OS can do:
- keep working
This is why I keep coming back to “surfaces”, “compositor”, and “contracts”.
If you get those words wrong, the system won’t just be slower.
It will be unreliable in a way that users can feel.
🔗The compositor is the reality check
An operating system compositor isn’t just layout.
It’s:
- surface lifecycles
- stacking
- focus
- output geometry
- presentation timing
- input routing
WEFT OS has a weft-compositor built in Rust using Smithay.
The compositor owns the display and composes surfaces.
The shell is intended to be a Wayland client of that compositor.
Applications are intended to be Wayland clients too.
That means:
- the shell doesn’t “own the screen”
- the shell isn’t secretly the display server
And it sets an important design goal:
- the shell should be able to crash and restart without automatically taking the whole session with it
🔗A custom shell protocol exists for a reason
Wayland already has protocols for many windowing concepts.
But WEFT has a specific bridging problem:
- the shell wants to represent windows as DOM elements
- the compositor owns the app surfaces
So WEFT defines a small, explicit protocol boundary between shell and compositor.
That protocol is defined for implementation planning and rigor, and it is explicitly not implemented yet.
I’d rather keep the seam explicit and argue about its size than pretend it doesn’t exist.
🔗Why this is a reasonable thing to attempt in 2026
This idea is not new.
The web stack has been proposed as an OS UI substrate for more than a decade.
The reason WEFT exists now is not that the idea got less controversial.
It’s that the surrounding primitives improved:
- Rust is a normal choice for systems code.
- WebAssembly isn’t just “a faster JavaScript”; it’s a portable compilation target with a real sandbox story.
- WASI exists as a capability-oriented interface model.
- Wayland is now the default direction on Linux.
- Smithay makes building a compositor in Rust feasible.
None of this guarantees success.
But it moves the idea from “pure fantasy” to “hard engineering”.
Hard engineering is the point.
🔗The architecture in one breath
WEFT OS is organized around three roles:
- A Wayland compositor (
weft-compositor), responsible for composing surfaces and routing input. - A system shell renderer (
weft-servo-shell), intended to render the desktop UI as HTML/CSS via Servo. - An application supervisor (
weft-appd), responsible for launching apps and brokering app sessions.
Applications are treated as two parts:
- a Wasm core (intended to be executed under Wasmtime)
- an HTML UI (intended to be rendered by Servo)
That split is not aesthetic.
It’s a security and reliability stance.
It also means I’m going to be painfully explicit in future posts about what is designed and what is implemented.
🔗A short list of non-negotiables
Here are a few constraints that I’m treating as non-negotiable for this project.
If any of these fail, the “desktop as a document” idea stops being interesting and becomes a liability.
🔗The shell cannot become a universal authority
If the shell ends up being the place where everything happens, we just reinvented a monolith with nicer CSS.
The shell should be powerful in presentation.
It should not be powerful in authority.
🔗Apps cannot become DOM children
If app content lives inside the shell’s DOM tree, isolation becomes a social convention.
WEFT’s model requires a compositor boundary.
🔗Performance must be treated as a contract
If the UI feels like a webpage, the project fails.
Not because webpages are bad.
Because the OS is judged by consistency.
That means the system must be designed around compositing rules and predictable frame pacing.
🔗Failure modes must be survivable
An OS that can’t survive component failure is not an OS.
It’s a demo.
🔗What I’m not going to do in this series
I’m not going to pretend this is already a polished OS.
I’m also not going to hide behind vagueness.
An OS is not “code that draws pixels”.
An OS is a set of promises:
- what can access your data
- what survives crashes
- what cannot happen even when software is malicious
- what stays fast after days of uptime
Those promises only become real when boundaries are explicit.
WEFT is attempting to make boundaries explicit early.
That means you’ll see a lot of “this is not implemented yet” in the early stages.
That’s not a weakness.
It’s how you avoid lying to yourself.
🔗Who this series is for
I’m writing this series for several groups that overlap more than they think:
- people who remember Firefox OS / Ubuntu Touch / Sailfish and still care
- people who care about Wayland and the Linux desktop as a systems problem
- people in the Rust and Servo ecosystems
- web platform people who care about HTML/CSS as serious UI technology
- OS architects who care about authority boundaries and failure modes
And yes, I’m writing it for people who think this is a terrible idea.
If you think it’s terrible, I want you to be specific about why.
🔗What comes next
The next post is a technical memoir: Firefox OS, Ubuntu Touch, Sailfish.
Not as an obituary, but as a re-reading.
They were right about the direction.
They were too early.
And WEFT is built in the shadow of that era — whether we like it or not.