Native Custom Elements
Shadow DOM, slots, part, CSS custom properties, form association. One tag that works wherever HTML works.
v0.1 prerelease — Rust/OXC compiler
Naos compiles typed component functions into platform-native Web Components — Shadow DOM, slots, events, and static HTML when you prerender. No virtual DOM. A small shared runtime kernel, not a framework runtime.
pnpm add @naos-ui/core @naos-ui/runtimeimport { event, state } from "@naos-ui/core"
export function Counter({ label = "Count" } = {}) {
const count = state(0)
const change = event<number>("change")
return (
<button
part="button"
onClick={() => {
count.update((value) => value + 1)
change.emit(count())
}}
>
{label}: {count()}
</button>
)
}
<!-- any framework — or no framework at all -->
<app-counter label="Clicks"></app-counter>
<script type="module" src="/counter.js"></script>
How it works
Write typed PascalCase component functions with state(), computed(), and typed events — a strict, React-like TSX subset.
The Rust/OXC compiler analyzes your TSX and generates native Custom Element modules. No virtual DOM anywhere in the output.
Deliver real Custom Elements with Shadow DOM, slots, and Declarative Shadow DOM prerendering. Consumers share a small runtime kernel, not a framework.
Why Naos
Everything Naos generates is standard browser technology. Your components do not depend on Naos being fashionable in five years — only on the web platform still existing.
Shadow DOM, slots, part, CSS custom properties, form association. One tag that works wherever HTML works.
A tree-shakeable kernel handles lifecycle, updates, styles, and DOM spreads. The complete internal kernel is about 6 kB gzip — not a framework runtime.
state(), computed(), and effect() update exactly what changed. No re-render cycles, no reconciliation passes.
A Rust/OXC core behind a thin TypeScript surface: fast parses, precise diagnostics, and a typed N-API boundary.
Static HTML with <template shadowrootmode> by default — markup that renders before JavaScript and hydrates on upgrade.
React, Vue, Angular, CMS pages, plain HTML. Build a component once, consume it as a native element everywhere.
Where Naos fits
Naos shares the "compiler-first, no virtual DOM" vocabulary of today's tools — but it compiles to native Custom Elements, ships a small shared runtime rather than a framework runtime, and updates with signals. Here is how that lands next to the tools you already know.
If a component should outlive the framework that renders it, author it once in Naos and ship it as a native element — instead of rebuilding it for React, Vue, and Angular in turn.