React, compiled to VanillaJS
Vidact reads your function components at build time and writes the DOM code for them. The component body runs once, at mount. A setState call after that reaches only the text nodes and attributes that read that state.
Get started
npx vidact my-app
Beta. Vidact compiles a documented subset of React 19 and refuses the rest at build time.
Four things, running here
Every example below is ordinary React, compiled by Vidact and mounted into this page.
CounterFormKeyed listBranches
Counter.tsx
import { useState } from 'react'export function Counter() {
const [count, setCount] = useState(0)
return (
setCount(count + 1)}>
Increment
Count: {count}
)
}
Result
IncrementCount: 0
Component calls1
DOM mutations0
Tree diffs0
Counted live by a MutationObserver watching this demo.
8.0 kB
A counter app, runtime included
tests/runtime-size/fixtures/counter.tsx
11.8 kB
TodoMVC, runtime included
examples/todomvc/src/TodoApp.tsx
0
Component calls after mount
the body runs once, at mount
Bundle sizes are gzipped
There is a framework around it
Vidact Start adds file routes, server loaders, SSR, hydration, and client navigation. The same compiler produces the server and the browser build, so the markup the server sends and the DOM the client hydrates come from one description of the component.
src/routes/products/$productId.tsx
import { defineFileRoute } from '@vidact/start'
const loader = async ({ params }) => ({
product: await findProduct(params.productId),
})
export function ProductRoute({ loaderData }) {
return {loaderData.product.name}
}
export const Route = defineFileRoute({
loader,
component: ProductRoute,
})
What it refuses
Class components, createRef, most of the Children helpers, and React DevTools are outside the subset. So is any third-party package that ships precompiled against React's runtime rather than React-shaped source.
None of that degrades quietly. The compiler stops the build at the line that caused it and names the API, and there is no fallback path that loads React instead.
build output
src/Clock.tsx:3:28: UnsupportedSyntax: React class components are unsupported; use a function component and Vidact errorBoundarysrc/Toggle.tsx:5:18: UnsupportedSyntax: unsupported React event prop onWiggle; use a supported React 19 event name




