Getting started

Scaffold a Voltro project and boot it locally in under a minute.

Voltro is an AI-first, multi-tenant, reactive full-stack framework. You write your backend through file conventions for queries, mutations, actions, streams, workflows, and agents; hooks for reactive data; automatic live updates to every connected client over a single WebSocket.

This guide gets you from zero to a running stack in under a minute.

Prerequisites

  • Node.js 24+ — Voltro relies on the --experimental-strip-types flag and modern ESM behaviour.
  • pnpm 10+ — workspaces, fast installs, deterministic lockfiles.
  • Postgres 16+ (optional) — Voltro's dev mode runs against an in-memory store by default; switch to Postgres when you want logical replication-backed subscriptions, durable workflows, or to mirror production locally.

Scaffold a project

A Voltro monorepo is a pnpm workspace. create-project walks up from your current directory looking for pnpm-workspace.yaml — and when there is none, it creates the workspace root right there before scaffolding. So an empty directory is a perfectly good starting point:

mkdir acme && cd acme

pnpx voltro create-project acme \
  --api api-backend \
  --web frontend-landing \
  --port-range 5190-5199

You get:

acme/
  pnpm-workspace.yaml     # the package globs + the install-script decisions
  package.json            # dev / build / test / typecheck (plain `pnpm -r` scripts)
  .gitignore              # incl. .env.local, where `voltro dev` mints your secrets
  .git/                   # unless you were already inside a repo
  AGENTS.md + CLAUDE.md   # the agent guide, seeded per project
  apps/acme/
    api/                  # Voltro backend
    web/                  # landing page
    project.json          # the project's port range + app map

The project name is kebab-cased (so Acme becomes acme). The --port-range is recorded in project.json so every new app added later gets a unique port without you thinking about it.

Three things worth knowing about this first run:

  • The install-script question is already answered. pnpm refuses to finish an install that has an undecided postinstall (ERR_PNPM_IGNORED_BUILDS), and a Voltro workspace pulls three — all transitive, none of them anything you picked. pnpm-workspace.yaml ships the answers with a reason on each line: esbuild: true (vite's compiler binary), @parcel/watcher and msgpackr-extract false (optional native accelerators with pure-JS fallbacks, so your first install needs no C++ toolchain). Change your mind with pnpm approve-builds.
  • Already have a workspace? Nothing is overwritten. An existing pnpm-workspace.yaml is left alone, and only root scripts you don't already define are filled in. To prepare a directory without scaffolding anything yet, run voltro init — it creates the same workspace root and stops there.
  • It registers the project with the cloud control plane (self-hosted tracking) unless you pass --no-register. Offline, in CI, or just not interested: --no-register skips the network call entirely.

Boot it

Install and run from the workspace root — there is no top-level acme/api to cd into; the project lives under apps/acme/:

pnpm install
pnpm dev

The root dev script is pnpm -r --parallel dev: it runs every workspace package that has a dev script, at once. No task runner to install — and apps that own their own dev loop (an Expo mobile app, a serverless bundle) simply don't define dev, so they opt out by construction. To run one app on its own, pnpm --filter @acme/api dev.

By default:

  • api listens on :4000 (RPC over WebSocket on /ws)
  • web listens on the first port in your range (e.g. 5190)
  • The framework dashboard auto-launches on :5179 (set VOLTRO_DASHBOARD=off to skip it)

Open the web app's URL in a browser — anything you edit in apps/acme/api/ or apps/acme/web/src/ hot-reloads.

What you just got

  • File-based queries (*.query.ts) and mutations (*.mutation.ts) — no manual registration
  • Streams (*.stream.ts) for one-shot server-to-client element feeds
  • Reactive subscriptions wired to Postgres logical replication (or in-memory CDC for the dev store)
  • Multi-tenancy as a runtime primitive — drop the tenant() mixin on a table and the runtime scopes reads + flags cross-tenant writes
  • Durable workflows via @effect/workflow — long-running jobs survive deploys and crashes
  • AI primitives wrapping the Vercel AI SDK, plus a tool-calling convention
  • End-to-end type safety from your Postgres schema to your React components, no codegen step

Next steps

  • Why Voltro? — the bigger picture + what we won't build
  • Concepts — the vocabulary behind the framework
  • File conventions — what *.query.ts, *.mutation.ts, etc. actually do
  • Data overview — queries, mutations, actions, streams in five minutes