A next-generation web component framework. Not an evolution of what exists — a rethink from first principles.
Install the core framework:
npm install @micronjs/core# Core framework
npm install @micronjs/core
# Optional packages
npm install @micronjs/css
npm install @micronjs/router
npm install @micronjs/ai
npm install @micronjs/worker
npm install @micronjs/wasm
npm install @micronjs/islandsimport { $, $computed, component, el, text, each, when, on, bind } from '@micronjs/core';
import { cssSignal } from '@micronjs/css';
export default component('x-todo', {
props: { title: String },
setup({ title }) {
const items = $<string[]>([]);
const input = $('');
const filter = $<'all' | 'done'>('all');
const add = () => {
if (!input().trim()) return;
items.update(list => [...list, input()]);
input.set('');
};
const filtered = $computed(() =>
filter() === 'done' ? items().filter(i => i.startsWith('✓')) : items()
);
// CSS Custom Property binding
cssSignal(document.documentElement, {
'--todo-accent': $computed(() => items().length > 0 ? '#4f46e5' : '#94a3b8'),
});
return el('div', { class: 'todo' }, [
el('h1', text(title)),
el('div', { class: 'input-row' }, [
el('input', { ...bind(input), placeholder: 'Add item…' }),
el('button', { ...on('click', add) }, text('Add')),
]),
el('ul', each(filtered, (item, i) =>
el('li', { key: i, class: 'item' }, text(item))
)),
when(
$computed(() => items().length === 0),
el('p', { class: 'empty' }, text('Nothing yet.'))
),
]);
},
});| Bet | What exists today | What X does |
|---|---|---|
| WASM reactive core | JS signal graphs (GC, JIT variance) | Rust compiled to WASM — linear memory, zero GC, predictable sub-μs propagation |
| SharedArrayBuffer signals | postMessage to share state between threads | Signals live in SAB — atomic reads/writes, zero serialization cost |
| Off-main-thread rendering | All frameworks run on the main thread | RenderWorker owns the reactive runtime; main thread only applies DOM patches |
| Binary resumability | JSON state serialization + constructor re-run | WASM memory snapshot → client restores and is immediately interactive |
@micronjs/core — Signals ($, $computed), scheduler, el() hyperscript, component(), context
@micronjs/worker — RenderWorker, DomPatcher, binary PatchRingBuffer protocol
@micronjs/wasm — Rust reactive core (lib.rs) + TS fallback + auto-loader
@micronjs/css — cssSignal(), cssVar(), defineTheme(), adoptedStyleSheet()
@micronjs/router — XRouter, defineRoute<TParams, TData>(), typed navigation
@micronjs/ai — stream(), infer(), reactiveStream() — AI-native streaming primitives
@micronjs/islands — captureSnapshot(), injectSnapshot(), resumeFromDOM() — binary resumability
import { $, $computed, component, el, text, each, when, on, bind } from '@micronjs/core';
import { cssSignal } from '@micronjs/css';
export default component('x-todo', {
props: { title: String },
setup({ title }) {
const items = $<string[]>([]);
const input = $('');
const filter = $<'all' | 'done'>('all');
const add = () => {
if (!input().trim()) return;
items.update(list => [...list, input()]);
input.set('');
};
const filtered = $computed(() =>
filter() === 'done'
? items().filter(i => i.startsWith('✓'))
: items()
);
// CSS Custom Property binding — zero per-element JS
cssSignal(document.documentElement, {
'--todo-accent': $computed(() => items().length > 0 ? '#4f46e5' : '#94a3b8'),
});
return el('div', { class: 'todo' }, [
el('h1', text(title)),
el('div', { class: 'input-row' }, [
el('input', { ...bind(input), placeholder: 'Add item…' }),
el('button', { ...on('click', add) }, text('Add')),
]),
el('ul', each(filtered, (item, i) =>
el('li', { key: i, class: 'item' }, text(item))
)),
when(
$computed(() => items().length === 0),
el('p', { class: 'empty' }, text('Nothing yet.')),
),
]);
},
});When Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp headers are set (required for SharedArrayBuffer), signals store scalar values directly in shared memory. A signal write is one Atomics.store. Workers can read signal values without postMessage.
import { $, sabAvailable, signalVersion } from '@micron/core';
const count = $(0);
console.log(sabAvailable()); // true if COOP/COEP set
// In a compute worker — reads count without postMessage:
// const val = Atomics.load(sharedBuffer(), signalSlot(count));
count.set(5); // Atomics.store into SAB slot
count.update(n => n + 1); // read-modify-write
count.peek(); // untracked read
count.map(n => n * 2); // derived ReadonlyXSignal<number>Falls back to plain JS closures transparently when SAB is unavailable.
import { RenderWorker, DomPatcher, registerNode } from '@micron/worker';
// Main thread — only applies DOM patches
const worker = new RenderWorker('/x-render-worker.js');
const patcher = new DomPatcher(worker.ringBuffer);
registerNode(0, document.getElementById('app')!);
patcher.start();
await worker.mount('x-todo', 'app', { title: 'My Todos' });
// Everything else (signal graph, effects, reconciliation) runs in the worker.
// The main thread budget is ~0% framework, ~100% paint.- Synchronous (dev / fallback) —
component()mounts and updates the DOM directly on the main thread. This path works everywhere (no COOP/COEP headers). Perfect for Storybook, quick demos, and environments where SharedArrayBuffer is unavailable. - Worker (production) — the RenderWorker evaluates the EdNode tree, diffs keyed lists, and writes DOM patches into the ring buffer; the main thread’s
DomPatchersimply applies them. The component API is identical: the only difference is how you bootstrap the app.
Switching between the two modes is a build-level decision. Local development can rely on the synchronous path, while production bundles wire up the worker entry point and load COOP/COEP headers for SAB-backed signals.
-
Main thread bootstrap
import { RenderWorker, DomPatcher, registerNode } from '@micron/worker'; const worker = new RenderWorker(new URL('/x-render-worker.js', import.meta.url)); const patcher = new DomPatcher(worker.ringBuffer); registerNode(0, document.getElementById('app')!); patcher.start(); // Optional: wire low-latency notifications worker.notifyPort.onmessage = () => patcher.drainSync?.(); await worker.mount('x-app', 'app', { initialCount: 5 });
-
Worker entry (
x-render-worker.ts)import { RenderWorkerRuntime } from '@micron/worker'; import '../dist/components/x-app.js'; // ensure components are registered RenderWorkerRuntime.init();
-
Headers + hosting — serve the bundle with
Cross-Origin-Opener-Policy: same-originandCross-Origin-Embedder-Policy: require-corpso SAB-backed signals and the patch ring buffer are shared between threads. -
Testing parity — run Storybook (synchronous path) for ergonomics, then run E2E smoke tests that boot the worker build to ensure parity before shipping.
import { stream, infer } from '@micron/ai';
import { el, text, when, component, $ } from '@micron/core';
component('x-chat-reply', {
props: { prompt: String },
setup({ prompt }) {
const reply = stream(
fetch('/api/chat', {
method: 'POST',
body: JSON.stringify({ prompt: prompt() }),
})
);
return el('div', { class: 'reply' }, [
text(reply.text), // updates per-token, zero re-render
when(reply.loading, el('span', { class: 'cursor' }, text('▌'))),
when($computed(() => reply.error() !== null),
el('p', { class: 'error' }, text(reply.error as any))
),
]);
},
});Works with OpenAI SSE, WebSocket, ReadableStream, EventSource, and any AsyncIterable<string>.
import { defineRoute, XRouter, buildPath } from '@micron/router';
import { z } from 'zod'; // optional schema
const userRoute = defineRoute({
path: '/users/:id',
schema: z.object({ id: z.string().min(1) }),
loader: ({ id }) => fetchUser(id),
component: ({ params, data, loading }) =>
when(loading, el('span', text('Loading…')), userCard(params, data)),
});
const router = new XRouter({ routes: [userRoute.def] });
await userRoute.go(router, { id: '42' }); // TypeScript error if params wrong// Server
import { renderIsland, captureSnapshot, injectSnapshot } from '@micron/islands';
import { createReactiveCore } from '@micron/wasm';
const core = createReactiveCore();
// ... run SSR render ...
const snap = captureSnapshot(core);
const page = injectSnapshot(ssrHtml, snap);
// Client — zero re-render, zero re-parse
import { resumeFromDOM } from '@micron/islands';
const { core, signalValues } = await resumeFromDOM();
// App is interactive immediatelyimport { cssSignal, cssVar, defineTheme } from '@micron/css';
import { $ } from '@micron/core';
const $theme = $<'light' | 'dark'>('light');
// All CSS rules using these vars update in one browser-native pass
cssSignal(document.documentElement, {
'--bg': $theme.map(t => t === 'dark' ? '#0f172a' : '#fff'),
'--fg': $theme.map(t => t === 'dark' ? '#f1f5f9' : '#111'),
'--accent': $('4f46e5'),
});
// In CSS:
// body { background: var(--bg); color: var(--fg); }
$theme.set('dark'); // instant, zero JS per elementThe reactive graph is implemented in Rust (packages/wasm/src/lib.rs) and compiled to WASM via wasm-pack. The TypeScript fallback (packages/wasm/src/fallback.ts) provides identical semantics when WASM is unavailable.
cd packages/wasm
cargo install wasm-pack
wasm-pack build --target web --out-dir ./pkg| Feature | React | Solid | Svelte | Qwik | X |
|---|---|---|---|---|---|
| Reactive primitive | Hook (re-render) | Signal (fine-grained) | Rune (compiled) | Signal | Signal (WASM+SAB) |
| Cross-thread state | postMessage | postMessage | N/A | postMessage | SharedArrayBuffer |
| Main thread work | High | Medium | Low | Low | Near zero |
| Hydration cost | Full re-render | Full re-render | Full re-render | Resumable (JS) | WASM binary restore |
| CSS updates | class/inline | class/inline | class/inline | class/inline | CSS Custom Properties |
| AI streaming | Addon | Addon | Addon | Addon | Core primitive |
| Component format | JSX | JSX | SFC | JSX | Typed TS (no transform) |
| Package | Scope | Status |
|---|---|---|
@micron/core |
Signals, scheduler, hyperscript, component + context APIs | ✅ Implemented (TypeScript) |
@micron/worker |
RenderWorker, DomPatcher, patch protocol, SAB transport | 🚧 Prototype ready — needs browser integration + tests |
@micron/wasm |
Rust reactive core + WASM bindings | ✅ Compiles via wasm-pack; integration work pending |
@micron/css |
cssSignal, cssVar, theme helpers |
🚧 API skeleton — polish + docs required |
@micron/router |
Typed routes, navigation helpers | 🧪 Spec draft — implementation in progress |
@micron/ai |
stream, infer, reactive streaming primitives |
🧪 Experimental — SSE/WebSocket adapters prototyped |
@micron/islands |
Binary snapshot capture/resume tooling | 🧭 Design + API sketches; implementation upcoming |
This is a proof-of-concept / research prototype. The architecture is fully designed and the TypeScript layer is implemented. The WASM reactive core (lib.rs) is production-ready Rust and compiles with wasm-pack. The off-main-thread rendering system needs integration testing in a real browser environment with COOP/COEP headers.
The goal: demonstrate that these four bets are technically viable together, not just in isolation.