Skip to content

Installation

This page gets a Stator project onto disk and the dev loop running.

Terminal window
pnpm create stator my-app
# or pick a starter: --template minimal | todomvc | desksmith | live-poll | with-auth | weather | registration
# (any repo works too: --template github:user/repo/path; pin first-party templates with --ref <branch|tag>)
cd my-app && pnpm install && pnpm dev

The scaffold is a complete working app — a counter machine, a .stator page, and the stator CLI scripts (dev, build, start, check, test). The rest of this page is a tour of what create-stator just wired for you.

  • Node.js (current LTS or newer) and a package manager (npm, pnpm, or yarn).
  • TypeScript — Stator is TypeScript-first; machines and props are fully typed.
Terminal window
npm i @statorjs/stator

Stator publishes several entry points; you import from the one that matches the layer you’re in:

  • @statorjs/stator/serverdefineMachine, stores, logger, createApp.
  • @statorjs/stator/configdefineConfig for stator.config.ts.
  • @statorjs/stator/templateread, each, when, raw, …
  • @statorjs/stator/clientStatorElement, use, machine (client islands).
  • @statorjs/stator/components — shipped components like <JsonLd>.
  • @statorjs/stator/dev and @statorjs/stator/buildcreateDevApp / buildApp for hand-wiring a custom entry (most apps use the CLI instead — see below).

A Stator app is organized by convention:

my-app/
├── machines/ # defineMachine definitions (one per file)
├── routes/ # .stator pages and .ts API routes (file-based)
├── templates/ # reusable .stator components and layouts
├── static/ # served as-is
└── stator.config.ts # optional — store, sessions, port (defaults apply if absent)

Files in machines/ and routes/ are auto-discovered — there’s no central registry to maintain, and no entry file to hand-wire: the stator CLI is the entry point.

The scaffold’s package.json scripts are thin wrappers over the stator CLI, which owns the whole dev / build / serve loop:

{
"scripts": {
"dev": "stator dev",
"build": "stator build",
"start": "stator start",
"check": "stator check",
"test": "stator test"
}
}
  • stator dev — the dev server: live reload, the wire inspector, and on-the-fly .stator compilation. Replaces the hand-written server.ts earlier versions needed.
  • stator check — typechecks the whole stack: it regenerates the per-component .stator.d.ts declarations and runs tsc over the server in one step, so a broken import or a bad prop fails check (this replaces the old sync.ts + tsc dance).
  • stator build — compiles the app to dist/, running check first so a broken build can’t ship.
  • stator start — serves a built dist/ in production.

The compiler writes its declarations into a framework-managed .stator/ directory — add it to .gitignore.

Defaults — in-memory state, port 3000, dev inspector on — need no config file at all. To change them, add a stator.config.ts at the app root:

import { defineConfig } from '@statorjs/stator/config'
import { RedisStore } from '@statorjs/stator/server'
export default defineConfig({
persistence: { session: new RedisStore(process.env.REDIS_URL!) },
sessions: { ttlSeconds: 86_400 },
// secret, cors, trustedOrigins, realtime, dev, port — all optional
})

Config is grouped by concern (persistence, sessions, realtime, dev, port, …), and every field is optional. .env and .env.local are loaded automatically, so a REDIS_URL or a secret can come from the environment rather than source.

  • Quick start — a machine, a route, and an event, end to end.