Take the DOM off. Feel everything.
Rust Demo: https://fui-rs-demo.effindom.dev/
AssemblyScript Demo: https://fui-as-demo.effindom.dev/
Let’s be honest: nobody ever liked the feeling. Not you. Not the W3C. Not even Brendan Eich, who knocked JavaScript together in ten days and has been watching us fumble with it for three decades like a bad prophylactic that won’t tear.
The DOM was a document viewer. We stretched it over application architecture like a latex glove three sizes too small. Every framework since has been a different brand of “ultra-thin” — same discomfort, better marketing. React gave us a virtual one. Svelte promised a thinner one. None of them addressed the fundamental problem: you’re still wearing one.
EffinDom is what happens when you stop pretending the DOM is fine and build a real runtime instead. Go raw. Feel the performance. The browser was always a display server — we just forgot.
EffinDom was born on the web, which is the harder direction. A runtime designed around browser and WebAssembly constraints is inherently easier to carry onto native operating systems than a native-first runtime is to force back through the browser. The same retained runtime now runs directly on macOS, Windows, and Linux without Chromium or a system WebView. Android and iOS are the next targets.
EffinDom treats the browser as a display server + syscall surface — not as an application framework. It’s a three-tier stack closer to WPF, Qt, or SwiftUI than anything the web has seen before:
Tier 1 — Core (effindom-core.wasm): Stateless C++ microkernel. Controls
the WebGL context, drives Skia, handles raw drawing instructions. Dumb,
fast, memory-safe. Knows nothing about UI or text.
Tier 2 — UI (effindom-ui.wasm): Retained-mode runtime. Yoga flexbox
layout, HarfBuzz + ICU text shaping, input routing, semantics projection,
focus management. Runs isolated from the GPU.
Tier 3 — SDKs and language bindings: Typed, retained-mode app-facing APIs. FUI-AS and FUI-RS are available today; FUI-CS and FUI-KT have smoke/runtime validation coverage. Declarative fluent syntax. Fine-grained reactivity. No HTML. No CSS. No virtual DOM diffing.
Once the Tier 1 + Tier 2 engine DLLs are cached in your browser (CDN, forever), your actual app payload is tiny — the hello-world scaffold is under 100 KB over the wire, and real apps typically land in the low hundreds. Every app built on EffinDom shares the same cached runtime — no duplicate engine downloads, no framework tax.
The shared Tier 1/Tier 2 runtime is continuously validated on macOS arm64/x64, Linux x64/arm64, and Windows x64/arm64. Native-host packaging remains separate from the browser runtime npm package.
npx Scaffolding — npm create @effindomv2/fui-as-app and
npm create @effindomv2/fui-rs-app, each with simple and mvc blueprints.
→ create-fui-as-app repoGame engines. Built for scenes and sprites, not application typography, layout, or accessibility. An opaque canvas is a black box to screen readers, password managers, and browser devtools. EffinDom projects a full semantic tree through the browser bridge — assistive tech works out of the box.
A mobile framework compiled for the web. Monolithic payload (engine + Dart runtime + app). Two Flutter apps = two engine downloads. EffinDom’s Web DLL architecture shares one cached runtime across every app. Plus you’re not locked into Dart — write AssemblyScript, Rust, or Kotlin.
Desktop frameworks that treat the browser as a dumb glass panel. 5–15 MB app payloads. Broken mobile text input because they fight the OS instead of orchestrating it. EffinDom’s browser bridge projects a hidden DOM that lets iOS and Android provide native text selection handles, autocorrect, and IME composition.
Three.js is a game engine. Flutter is a mobile framework compiled for the web. egui is a desktop GUI ported to WASM. EffinDom is a POSIX-style display server for WebAssembly UI — web-native, not web-ported.
Web-native means the architecture was designed for the browser’s actual physics. The Tier 1 and Tier 2 runtimes are immutable, content-hashed WASM modules served from a CDN. Once cached locally, they’re shared across every EffinDom app — no duplicate engine downloads, no monolithic blobs. The ICU data, the fonts, the HarfBuzz shaper, all cached forever. Your app is just your business logic (the hello-world scaffold is under 100 KB over the wire; real apps land in the low hundreds). Flutter, Compose, and egui can’t do this — they were ported to the web, not built for it.
| Repo | Purpose |
|---|---|
| EffinDOM | Runtime, browser bridge, core engine, docs |
| fui-as | AssemblyScript SDK + controls + app surface |
| fui-rs | Rust SDK + controls + app surface |
| fui-cs | Early-stage C# SDK with unit and browser-smoke coverage |
| fui-kt | Early-stage Kotlin/Wasm SDK with smoke/runtime coverage |
| create-fui-as-app | npx scaffolder CLI |
| create-fui-rs-app | npx scaffolder CLI |
| Package | License |
|---|---|
@effindomv2/runtime |
MIT |
@effindomv2/fui-as |
AGPL-3.0-only or commercial |
@effindomv2/fui-rs |
AGPL-3.0-only or commercial |
@effindomv2/fui-cs |
AGPL-3.0-only or commercial |
@effindomv2/fui-kt |
AGPL-3.0-only or commercial |
@effindomv2/create-fui-as-app |
MIT |
The runtime is MIT — use it freely. The SDKs are AGPL because I’m a solo maintainer with a young family, building this at night. I’m asking for funding to hire a contributor and keep this sustainable. If you’re building something commercial, there’s a license for that. It’s how this stays alive.