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.
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.
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.
Read the Start guidesrc/routes/products/$productId.tsx
import { defineFileRoute } from '@vidact/start'const loader = async ({ params }) => ({ product: await findProduct(params.productId),})export function ProductRoute({ loaderData }) { return <h1>{loaderData.product.name}</h1>}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.
See every API and its status