Web-born. Native without a browser.

A real application ecosystem beyond the DOM.

EffinDOM combines a retained cross-language runtime, typed FUI SDKs, project scaffolders, native packaging, shared delivery, and developer tooling. Build for the browser through WebAssembly or run directly on macOS, Windows, and Linux.

Ecosystem topology Live / v2
Tier 3 · Application SDKs FUI-RS / FUI-AS Retained controls, themes, events, and application APIs
Tier 2 · UI runtime Layout / Text / Input / Semantics Yoga, HarfBuzz, ICU, accessibility projection
Tier 1 · Renderer Skia command processor GPU-backed presentation with software fallback
Browser / WASM
Native desktop

The premise

The browser is an excellent display server. It should not dictate your application architecture.

Myth versus implementation

Popular canvas myths, debunked.

These common beliefs are accurate for a raw bitmap with mouse events, but they are not inherent limitations of canvas presentation. Here is what EffinDOM actually implements instead.

“Canvas applications are inaccessible.”

A raw canvas is. EffinDOM separately projects its retained semantic tree through DOM and ARIA in browsers, NSAccessibility on macOS, Microsoft UI Automation on Windows, and AT-SPI on Linux. Assistive technology receives controls, names, state, bounds, actions, focus, and editable text rather than being asked to interpret pixels.

Inspect the accessibility implementation ↗

“You cannot inspect anything in DevTools.”

Controls are intentionally not DOM layout elements, so the CSS inspector is not the right debugger. EffinDOM exposes its retained tree, semantic tree, bounds, state, and node properties through an on-demand DevTools DOM mirror, Inspect Mode, and a built-in debug dialog. You inspect the model that actually owns the UI.

“Text input, IME, and password managers will be broken.”

EffinDOM mirrors editor state into real browser editing and form elements while retaining visual rendering itself. This lets the browser and operating system handle composition, mobile keyboards, clipboard conventions, autofill, and password-manager extensions.

“Users cannot select, copy, or search canvas text.”

Retained text supports caret placement, mouse and touch selection, cross-node ranges, teardrop handles, context menus, and clipboard operations. The normal desktop shortcut opens EffinDOM's retained find experience. Mobile and explicit browser-native find search the projected semantic text too; the match works, although the browser's highlight can use a slightly different DOM font from the canvas-rendered text beneath it.

“Canvas means redrawing everything forever.”

EffinDOM is retained and demand-driven. Controls preserve identity, layout and text results are cached, static content is reused, and frames are requested by invalidation or active animation. A canvas presentation surface does not require an immediate-mode application model or a permanent render loop.

“Every application ships another enormous WASM engine.”

Tier 1, Tier 2, ICU, and built-in fonts are immutable, content-addressed runtime assets shared across EffinDOM applications. The current demo transfers about 7.6 MB compressed from a cold cache, excluding page images, and under 500 KB for a warm home-page load. Browser caches can still be evicted; this is architecture, not magic.

“Canvas applications are invisible to search engines and bots.”

Client-rendered React is no different. Google can render a client application and index the semantic DOM produced after startup. In EffinDOM, application and UI state run in WebAssembly; the retained WASM runtime emits a semantic buffer, and the small browser bridge materialises that buffer as DOM and ARIA. React produces its client-rendered DOM from JavaScript instead. A rendering crawler can inspect either result; a crawler that never runs the client runtime sees neither application tree. Canvas presentation does not make EffinDOM uniquely opaque to bots.

Google's JavaScript SEO guidance ↗

“Native support is just an Electron or WebView wrapper.”

Native hosts run the EffinDOM C++ runtime directly against Metal, Direct3D 12, or Vulkan. There is no embedded Chromium and no system WebView. The browser and native hosts share retained UI behaviour, while platform adapters handle operating-system-specific services.

The whole stack

More than a runtime.

EffinDOM is the common foundation for a growing application ecosystem. Developers normally enter through an FUI SDK or a scaffolder; the rendering runtime, browser bridge, native hosts, delivery system, and packaging engine sit underneath.

Application SDK

FUI-RS

Retained Rust UI for browser and native desktop, with Cargo-native tooling and an npm-oriented browser workflow.

SDK, docs, and source ↗
Application SDK

FUI-AS

AssemblyScript application development with a TypeScript-shaped fluent API and independently loaded route WASM.

SDK, docs, and source ↗
Shared infrastructure

EffinDOM Runtime

Rendering, layout, typography, input, selection, semantics, browser integration, and native platform hosts.

Runtime source and docs ↗
Rust developer tooling

cargo-fui

Scaffold, develop, build, and package FUI-RS applications for web, native, or universal targets.

Install from crates.io ↗
Packaging engine

Native Packaging

Cross-language application metadata, icon generation, signing inputs, and packages for six desktop targets.

Packaging crate and source ↗
Browser scaffolder

create-fui-*-app

npm-oriented simple and routed project templates for FUI-RS and FUI-AS browser applications.

Open the FUI-RS scaffolder ↗
Shared delivery

Runtime CDN

Immutable content-addressed WebAssembly runtimes, ICU data, and fixed assets shared across EffinDOM applications.

Inspect published runtime sets ↗
Agent guidance

FUI-RS Skills

Official, versioned Agent Skills that teach retained FUI-RS architecture, drawing, fonts, host integration, accessibility, and packaging.

Install the official skills ↗
Community application

Galaga-RS

The first independent FUI-RS application: a complete community-built Galaga-style space shooter with a live web build.

Source and live demo ↗
Incubating SDKs

FUI-KT / FUI-CS

Kotlin/Wasm and C# language surfaces currently at smoke-stage maturity, built against the same language-neutral ABI.

Follow the ecosystem ↗

Why EffinDOM

Born in the harder direction.

Native-first frameworks usually arrive on the web as ports. EffinDOM began with browser constraints: accessibility, IME, password managers, touch, routing, asynchronous assets, and a globally cacheable runtime. Moving that architecture onto native operating systems is the simpler direction.

01 / RENDERING

Retained, not reconstructed

Layout, text, hit testing, scrolling, and control state live in one retained runtime without virtual DOM diffing.

02 / WEB

Canvas without the black box

EffinDOM projects semantics and editor state separately, preserving ARIA, IME, selection, and password-manager integration.

03 / NATIVE

No Chromium. No WebView.

The same runtime executes directly through native macOS, Windows, and Linux hosts with platform accessibility adapters.

04 / TEXT

Typography is infrastructure

HarfBuzz and ICU provide shaping, line breaking, BiDi, global scripts, rich text, editing, and fallback-font handling.

05 / DELIVERY

A shared Web DLL

Content-addressed runtime modules and fixed assets can remain cached across routes, applications, SDKs, and languages.

06 / LANGUAGE

The runtime is not the SDK

A stable C ABI keeps rendering infrastructure language-neutral. Rust and AssemblyScript are first-class application surfaces.

Six native desktop targets.

Native applications run the EffinDOM engine directly. GPU acceleration uses the platform renderer below, with automatic software raster fallback when a suitable GPU surface is unavailable.

macOS ARM64
Apple Silicon Metal
macOS x64
Intel Mac Metal
Windows ARM64
Windows on ARM Direct3D 12
Windows x64
Windows PC Direct3D 12
Linux ARM64
Linux ARM Vulkan
Linux x64
Linux PC Vulkan

The hard parts

A canvas is easy. An application platform is not.

Drawing controls was never the difficult part. The work is in the behaviour users notice only when it is missing: editing, selection, international text, accessibility, native input, and state that survives real application use.

Editing

IME, clipboard, and password managers

Browser editor mirrors let canvas-rendered TextInput and TextArea controls cooperate with composition, autocorrect, platform clipboard conventions, forms, and password-manager extensions.

Global text

CJK and emoji without permanent tofu

HarfBuzz and ICU shape global scripts while incremental font fallback detects missing glyphs, loads only required coverage, and keeps live text stable as new fonts arrive.

Selection

Selection that crosses boundaries

Mouse drag, reverse selection, cross-node ranges, touch teardrops, handle crossover, context menus, copy, and viewport auto-scroll share one retained selection model.

Accessibility

Pixels are not the semantic tree

EffinDOM projects retained semantics through DOM and ARIA on the web, NSAccessibility on macOS, Microsoft UI Automation on Windows, and AT-SPI on Linux.

TextArea

Fast paths without behavioural forks

Visible-line processing, incremental edits, fixed line heights, monospaced metrics, wrapping, and static-content reuse reduce work while preserving identical Unicode, caret, hit-testing, and selection behaviour.

Native feel

Input follows the host platform

Native trackpad momentum, wheel behaviour, keyboard conventions, multi-click timing, window resizing, system themes, accent colours, and platform context menus are handled by host adapters rather than approximated globally.

Lifecycle

Retained state stays retained

Control identity preserves focus, text, selection, scroll position, overlays, and subscriptions. Browser history can restore named retained state instead of reconstructing a blank page.

Delivery

Fonts and runtimes load without freezing the app

Mandatory runtime assets expose bounded startup progress. Optional script coverage and page fonts load asynchronously, update retained content when ready, and do not block an already usable application.

Host services

Typed access beyond the UI runtime

Applications declare their own host-service boundary and generate strongly typed SDK bindings. Browser or platform code implements the capability without leaking bridge calls, raw pointers, or transport details into application UI.

Workers

Background work without blocking interaction

FUI workers run computation outside the application UI thread with generated message contracts, progress reporting, cooperative yields, cancellation, and an explicit allowlist of host services available inside the worker.

Choose your surface

Typed SDKs. One runtime.

FUI SDKs provide retained controls, fluent composition, reactive state, theming, accessibility, and application lifecycle without exposing the runtime ABI.

Web

FUI-AS

A TypeScript-shaped AssemblyScript SDK with fluent retained controls and compact route-level WebAssembly applications.

Browser application
npm create @effindomv2/fui-as-app@latest my-app

Same retained model. Native syntax.

The runtime concepts do not change between languages. Controls, capabilities, layout, and fluent configuration remain recognisable; each SDK only adapts composition and naming to its language.

FUI-RS Rust
fn build_page() -> FlexBox {
  ui! {
    column()
      .gap(12.0)
      .fill_width()
      .padding(24.0, 24.0, 24.0, 24.0) {
        text("Profile").font_size(28.0),
        row().gap(8.0) {
          text_input()
            .placeholder("Name")
            .fill_width(),
          button("Save"),
        },
      }
  }
}
FUI-AS AssemblyScript
function buildPage(): FlexBox {
  return Column(
    new Text("Profile")
      .fontSize(28.0),
    Row(
      new TextInput()
        .placeholder("Name")
        .fillWidth(),
      new Button("Save"),
    ).gap(8.0),
  )
    .gap(12.0)
    .fillWidth()
    .padding(24.0, 24.0, 24.0, 24.0);
}

AI-native developer experience

Agents that understand the framework.

Generic models often mistake retained UI for React-style rerendering or immediate mode. FUI-RS ships official Agent Skills grounded in released APIs, so an agent can follow the real ownership, lifecycle, rendering, accessibility, and packaging contracts instead of inventing plausible-looking framework code.

01 / APPLICATIONS

Retained app development

Fluent ui! composition, cheap retained handles, callbacks, capability traits, state ownership, and universal application boundaries.

02 / CONTROLS

Custom controls

Reusable components, templates, presenters, themes, focus, activation, semantics, and cycle-safe Rust ownership.

03 / DRAWING

Immediate and bitmap graphics

CustomDrawable, DrawContext, paths, text resources, retained bitmaps, dirty-region uploads, animation, and measured invalidation.

04 / TYPOGRAPHY

Custom font registration

Font faces, families, weight and style mapping, mixed-script fallback, async readiness, and web/native asset packaging.

05 / HOST

Generated host services

Typed service and event contracts, browser and native adapters, worker allowlists, subscriptions, and ABI-safe generation.

06 / ACCESSIBILITY

Semantic behaviour

Retained semantic projection, custom-control accessibility, forms, editors, keyboard operation, and assistive-technology testing.

07 / DELIVERY

Build and package

cargo-fui project targets, verified runtime acquisition, offline builds, icons, assets, DMG, MSIX, AppImage, and cross-platform CI.

See it running

Not a mock-up.

Retained controls, text editing, custom drawing, touch interaction, and a community-built space shooter, all running through FUI-RS.

FUI-RS demonstration01
FUI-RS demonstration02
FUI-RS demonstration03
FUI-RS demonstration04
FUI-RS demonstration05

The operating model

Shared where it matters.

The expensive runtime is infrastructure, not application payload. Applications ship their own retained logic while browsers reuse cached engines, ICU data, and built-in fonts.

“Your app is your app. The engine should not be downloaded again for every site.”

EffinDOM publishes immutable runtime sets selected by capability. Web applications consume them through a small browser bridge with packaged fallback assets. Native applications consume the same engine architecture as platform runtime libraries.

3 Runtime tiers
6 Native desktop targets
1 Language-neutral ABI

Take the DOM off.

Build a retained Rust application for the browser and native desktop, or start with AssemblyScript on the web.