One program, not two.
No endpoints, no fetch calls, no client copy of your data to go stale. State lives in typed machines on the server, and templates read from them.
Stator is a TypeScript framework where your app’s state lives in machines on the server. An event goes up, a patch comes down. No API layer, no client store, nothing to hydrate.
One round trip, in three panes. Press something. This is also what the dev toolbar shows you.
The product list is gone from the page. One patch swapped this branch in.
Quiet. Try Checkout with an empty cart first.
[]
On this page the machine runs in your browser, so the page can sit on a CDN. In your app it runs on the server, and these are the events and patches that would cross the wire.
No endpoints, no fetch calls, no client copy of your data to go stale. State lives in typed machines on the server, and templates read from them.
Add live: true to a route and every open page that reads a changed machine updates, across sessions.
A component with a <script> becomes a client island: the same machine engine in the browser, as a custom element. The compiler checks what ships.
Business logic is a machine, so it tests with Node’s own runner. Nothing to install, no DOM, no mock server. This one covers the same cart rules you just pressed.
import assert from 'node:assert/strict'
import { it } from 'node:test'
import { createActor } from '@statorjs/stator/machine'
import CartMachine from '../lib/demo-cart.ts'
it('refuses to check out an empty cart', () => {
const actor = createActor(CartMachine).start()
actor.send({ type: 'CHECKOUT' })
assert.deepStrictEqual(actor.getSnapshot().value, ['idle'])
})Stator runs your TypeScript directly on Node 24 and ships its own dev server, type checker, test command and production build. The dev server runs your app the way production does.
The closest relative. The server holds the state, diffs it and patches the DOM. Stator brings that model to TypeScript, with state machines as the unit and state in a store you choose.
Pick LiveView when you can be on the BEAM and need to scale across nodes today.
The same HTML-over-the-wire instinct. Where they swap fragments, Stator sends typed events to typed machines and gets structured patches back.
Pick Hotwire when you are already a Rails shop and the app is shaped like CRUD.
The opposite default. React ships a renderer and marks files as server or client. Stator ships no renderer, and where code runs is decided by where you import it.
Pick React when ecosystem depth or the hiring pool matters most.
Stator is small because it says no. An optimistic update is a second copy of the truth, so there are none; what must be instant lives in a client island. Stator also runs on a single replica today, with scale-out planned.