JSX compiles to native DOM operations via a Rust compiler — no virtual DOM, no runtime diff. Built on signals and standard Web Components.
Caution
Alpha. APIs and architecture may change as we harden toward production.
OTF Web is a fullstack web framework on a Rust foundation. A single compiler and toolchain spans the entire application: JSX components, client-side rendering, hydration, static generation (SSG), server-side rendering (SSR), and server endpoints are all produced from one source. The compiler analyzes your JSX statically and emits the exact DOM operations needed — there is no virtual DOM and no reconciliation loop at all.
The compiler derives several small, focused intermediate representations from the
same AST — View, Reactivity, Server, Route, Metadata — and each backend turns
those into code for a target (CSR, Hydrate, SSG, SSR, API). One source, many IRs,
many targets. See ARCHITECTURE.md for the full design.
Install ES-Runtime (esdev 0.15 or newer) and
add the runtime and compiler/routes plugin to your app:
pnpm add @opentf/web
pnpm add -D @opentf/esdev-plugin-webConfigure the HTML entry, client entry and esdev.json as shown in the
plugin setup guide, then run esdev start.
The OTF templates in esdev create are awaiting their upstream plugin migration;
see the verified migration status before using them.
export default function Counter() {
let count = $state(0);
const doubled = $derived(count * 2); // no arrow needed — the compiler wraps it
return (
<div>
<p>{count} × 2 = {doubled}</p>
<button onclick={() => count++}>Increment</button>
</div>
);
}This compiles to a standard Custom Element built from direct DOM operations.
{count} becomes a single binding wired to one signal, so updating count
touches exactly that text node and nothing else.
- Signals —
$state,$derived,$effect,$ref; the compiler wires reactivity, so there's no manual.value. - Standard Web Components — every component compiles to a native Custom Element. Use it anywhere, with any tool.
- File-based routing — nested layouts, dynamic segments, catch-all routes, and route guards.
- Batteries included — forms, testing, i18n, MDX docs, and project
scaffolding via
esdev create(create-webis deprecated).
The runtime is a rendering-layer comparison against the React, Solid, and
Svelte 5 libraries. It's an honest one — no single operation is fastest, and the
create-row ops are ties at this timing resolution. See the
benchmarks page for the full tables,
methodology, and caveats. Reproduce locally with tsr bench -- all.
| Package | Purpose |
|---|---|
@opentf/web |
Runtime — signals, DOM operations, router, SSG. |
@opentf/web-cli |
SSG helpers and release output hooks for esdev builds. |
@opentf/web-compiler |
Native toolchain (otfwc) — compilation, docs indexing and binary resolution. |
@opentf/web-form |
Reactive forms with async validation. |
@opentf/web-test |
Testing utilities for native components. |
@opentf/web-docs |
MDX documentation theme — sidebar, callouts, TOC. |
@opentf/web-i18n |
Internationalization — ICU messages, Intl formatters, URL-prefix locale routing. |
create-web (deprecated — use esdev create) |
Legacy project scaffolder. |
| Path | What's here |
|---|---|
crates/ |
The Rust compiler and toolchain — parsing, semantic analysis, IRs, codegen, the otfwc binary. |
packages/ |
Published JS packages — runtime, toolchain, forms, testing, docs, i18n. |
website/ |
This project's docs site and playground (deployed at web.opentechf.org). |
benchmarks/ |
The js-framework-benchmark harness and aggregation scripts. |
For repository development, install ES-Runtime (esdev 0.15 or newer), the Rust
toolchain, pnpm, and tsr, then run pnpm install
at the root. Run workspace tasks from the root so pnpm's package links stay
inside esdev's project root.
The tasks in tasks.toml are the shared local and CI entry points:
tsr --list # Discover available tasks
tsr dev # Playground development server
tsr site-install # Install the site's locked, released packages
tsr site # Documentation development server
tsr build # Build the playground
tsr site-build # Build and prerender the documentation site
tsr site-preview # Serve the built documentation site
tsr test # Rust and esdev tests, including forms and i18n
tsr test-e2e # Browser tests (Chrome and matching ChromeDriver)The website is an independent pnpm project using published framework and plugin
packages. Its build configuration and lockfile live in website/; site tasks run
from that directory. You can also run esdev start, esdev build and
esdev preview directly there. Changes to workspace packages reach the site after
their released versions are updated in website/package.json.
For automatic Cloudflare deployment, set the build command to
bash scripts/build-site.sh with the repository root as the working directory.
The script installs esdev 0.15.0 (override with ESDEV_VERSION), installs the
website's locked dependencies, and builds website/dist. Keep the existing
Cloudflare deployment command; the root wrangler.jsonc points to that output.
Component sources compile on import through @opentf/esdev-plugin-web in
esdev's DOM realm: tsr test-web-docs-dom, tsr test-web-form, and
tsr test-web-i18n run them individually. Each test file runs in a separate
process, with a 30-second timeout and strict compiler errors configured in
esdev.test.json. The comparison benchmark toolchains still require Bun.
The configs follow the official project build configuration:
build.targets describes outputs, dev controls development, and top-level
plugins also apply to tests.
Tailwind v4 is compiled by esdev directly from the CSS import.
Full guides, API reference, and a live playground at https://web.opentechf.org/docs.
Current upstream starter, output-hook and release requirements are tracked in the esdev migration status.