Vue-style templates
Use v-if, v-for, v-model, and event bindings without introducing VNodes.
TypeScript components. Familiar templates. Standard Custom Elements.
COMPONENT FIRST
Use v-if, v-for, v-model, and event bindings without introducing VNodes.
Keep logic, template, and styles in one TypeScript file; compile at build time.
Bring in @elfui/chain only when a builder or runtime string template is useful.
Static structure is known at build time. Runtime never diffs or patches a component tree.
Derive design-system variants from a base component instead of duplicating an implementation.
Ship standard Custom Elements that can register and run in any frontend stack.
COMPONENT INHERITANCE
import { useExtend, useVariant } from "@elfui/core";
export const PrimaryButton = useExtend(Button)
.name("primary-button")
.build();
export const DangerButton = useVariant(
Button, "danger-button", setDangerTone
).build();Shared props, events, and base styles
Name the derived tag and append focused local styles.
Keep Button behavior and adjust only tone and visual semantics.
ARCHITECTURE
| Concern | ElfUI | Vue | React | Lit | Solid |
|---|---|---|---|---|---|
| Update model | Compile-time fine-grained DOM | Reactivity + VDOM | VDOM reconciliation | Template parts | Fine-grained DOM |
| Primary authoring | TS + HTML macro | SFC templates | JSX | Tagged templates | JSX |
| Runtime work | No VNodes or patch | Component runtime | Reconciler runtime | Small template runtime | Fine-grained runtime |
| Output | Standard Custom Elements | Vue components | React components | Web Components | JSX components |
| Component boundary | Browser-native tags | Framework component | Framework component | Browser-native tags | Framework component |
SIZE SNAPSHOT
BROWSER BENCHMARK
Size data is from the 2026-07-11 release-readiness report. Browser figures are same-day smoke medians for ElfUI regression tracking, not a cross-framework ranking.
CORE PRINCIPLES
Dynamic points are split at build time. No VNodes and no component-tree diff at runtime.
import { defineHtml, useRef }
from "@elfui/core";
const count = useRef(0);
const increment = () =>
count.set(count.peek() + 1);
export const Counter = defineHtml(`
<button @click=${increment}>
Count: ${count}
</button>
`);Find text, attributes, events, branches, and lists.
Generate an isolated update path for every state read.
Subscribe only to the state each dynamic point consumes.
Write real DOM and register a standard Custom Element.
ECOSYSTEM
Macro components, app mounting, and the main user-facing APIs.
↗02Compiles TypeScript macro components and powers build diagnostics.
↗03An optional chain builder and runtime string-template extension.
↗04VS Code completion, diagnostics, and macro-component authoring support.
↗START EXPLORING
$ npm i @elfui/core
$ npm i -D @elfui/vite-plugin