Overview
Dozens of dogfooded starter templates ship with the framework — backend shapes, frontend shapes, a serverless function library, and an Expo mobile app. voltro list-templates is the authority; scaffold any of them with one CLI call.
Voltro ships dozens of starter templates across the four kinds you actually deploy: backends (api-*), frontends (frontend-* plus changelog), a serverless library (edge-functions), and an Expo mobile app (mobile-app). Each is a small, opinionated, dogfooded reference you scaffold once and then own — no update channel, no lock-in.
voltro list-templates is the authority, not this page. It prints the
templates your installed CLI actually ships; the tables below cover the ones
worth a paragraph of explanation, and several ids exist that have no entry here.
If an id appears in the command's output and not below, it exists and works.
The CLI loads templates by walking voltro-templates/apps/<id>/; the directory name IS the template id you pass to --api / --web / --template.
# A project with a backend + a blank frontend:
voltro create-project acme --api=api-backend --web=frontend-blank
# Add another app to an existing project later:
voltro add-app marketing --template=frontend-landing --to acmeEach app gets its own port from the project's portRange, wired through pnpm dev, ready to edit.
Backend templates (--api=<id>)
The api-backend* shapes share the same minimal notes domain and differ only in the plugin/store wired on top. The rest are feature showcases — each a cohesive domain that exercises one whole slice of the framework end to end.
| Template | Best for |
|---|---|
api-backend |
The minimal Voltro backend: app.config.ts + schema + one streaming query + one tenant-guarded mutation. Start here. |
api-backend-mail |
api-backend + @voltro/plugin-mail and a React-Email welcome template you preview/send from the dashboard. |
api-backend-storage |
api-backend + @voltro/plugin-storage — public (CDN-direct) and private (policy + grants) objects with upload examples. |
api-backend-mariadb |
MariaDB-backed: binlog CDC real-time across replicas + file storage. The dogfooded shape for K8s multi-replica apps. |
api-durable |
The whole durable + reactive surface in one order-fulfillment domain: a workflow (step / sleep / awaitSignal approval gate), an event trigger that starts it, a signal-injecting mutation, a cron schedule, a table subscriber, a materialized aggregate, and a run-once startup hook. |
api-ai |
A RAG support agent: a vectorEmbedding() docs table, a search tool, a real defineAgent / defineAgentExecutor model loop, and a generateObject action. Boots zero-infra; needs an AI key only to run the agent. |
api-data-advanced |
The advanced schema DSL: the *.entity.ts / *.relations.ts split with eager .with(), full-text search, dbEnum, array / generated / encrypted columns, and declarative query caching — a small authors + books catalog. |
api-kv |
Durable ctx.kv on an external-event-sync domain: a sync cursor you can't recompute plus TTL-bounded idempotency markers, contrasted with ctx.store (the rows) and ctx.cache. Exercises the full KV surface (getOrElse / has / set+TTL / list / delete). |
api-auth |
Real user auth — @voltro/plugin-auth wired turnkey: password sign-up/in/out over HttpOnly session cookies + a strategy that resolves the session to a typed Subject. Zero-infra boot. |
api-rest |
Public REST + OpenAPI — defineRestRoute endpoints (query/path/body, scope guards, Idempotency-Key) + @voltro/plugin-openapi (Swagger UI at /docs, generated from the descriptors). Zero-infra boot. |
api-saas |
The SaaS plugin bundle — billing entitlements (a quota gate), in-app + console notifications, analytics events, and live presence, wired turnkey. One projects.create exercises billing + analytics + notifications together. |
api-observability |
Metrics + errors + tests — @voltro/plugin-prometheus (GET /metrics + a custom counter), @voltro/plugin-sentry (inert without a DSN), tracing, and a @voltro/testing unit test. Zero-infra boot. |
api-webhooks |
First-class webhooks — a signature-verified incoming *.webhook.tsx receiver (rejects forged traffic before your handler) + an outgoing defineEvent a mutation emits via a durable signed delivery workflow. Zero-infra boot. |
api-search |
Full-text search in sync — @voltro/plugin-search mirrors every table write into an index via the post-commit change tap; the synthesized search.query rpc returns tenant-scoped hits. Memory backend (zero infra); one line to Typesense/Meilisearch/Algolia. |
api-feature-flags |
Feature flags as code — @voltro/plugin-flags: kill-switch / %-rollout / targeting, a declarative gatedBy map + an in-handler requireFlag guard (both fail typed FlagDisabled), useFlag() on the web. Memory store. |
api-ratelimit |
Per-endpoint rate limiting — @voltro/plugin-ratelimit intercepts rpc: a default + rules (sliding-window / token-bucket, by subject/tenant/…), typed RateLimited auto-merged into the error union. Memory store. |
api-rbac |
Role → scope access control — @voltro/plugin-rbac: a role map, an interceptor resolving roles to scopes, and an in-handler permission(ctx, 'notes:write') guard (typed ScopeError). admin:full bypasses. Config-only. |
api-moderation |
Pre-commit content moderation — @voltro/plugin-moderation checks fields before the handler: a block rule rejects with typed ContentRejected, a flag rule queues for review. keywordProvider / aiProvider. |
api-row-history |
Row history + time-travel — @voltro/plugin-row-history snapshots every write via the change tap; rowHistory() (every version) + rowAsOf() (value at a past instant), read through handlers. Memory store. |
api-backend-deactivation |
The deactivation() mixin — lock a user out (deactivatedAt) while the row stays VISIBLE/queryable — the deliberate opposite of softDelete()'s hide+anonymise. Pure schema. |
api-governance |
Field encryption + GDPR + consent + retention — @voltro/plugin-governance: AES-256-GCM .encrypted() columns (plaintext to handlers, ciphertext at rest), admin-gated governance.export/erase, a consent ledger, retention sweeps. |
api-collab |
Local-first / CRDT collaborative editing — a documents table with a crdtText() body; concurrent edits from many clients CONVERGE via an authoritative server-side merge on the write path (no last-write-wins loser), then broadcast over the reactive engine. Zero-infra; pairs with frontend-collab. |
Every one of these is kind: 'api' — and voltro list-templates lists more api-* ids than the table above covers.
Frontend templates (--web=<id>)
Web shapes spanning every render mode — static, spa, ssr, isr, selective islands hydration — plus the reactive fullstack loop (and its local-first / CRDT variant).
Every frontend template is bilingual (en/de) out of the box, with the i18n strategy matched to its render mode: the hydrated/SSR shells use cookie i18n (<LocaleSwitcher>), the static/islands sites use URL-prefix i18n (/de/…, one pre-rendered HTML file per locale). frontend-i18n remains the dedicated URL-prefix reference. See URL strategies for why render mode decides.
| Template | Render mode | Best for |
|---|---|---|
frontend-blank |
— | Empty React + Vite shell with a layout and an index page. Start here for any custom UI. |
frontend-app |
full · reactive |
The reactive end-to-end loop — a web frontend WIRED to an api (useSubscription + useMutation + auto-optimistic). Pairs with api-backend. |
collab |
full · reactive · CRDT |
Local-first collaborative editor — a textarea bound to a crdtText() body; type in two tabs at once and the edits CONVERGE (server-authoritative CRDT merge, no last-write-wins loser). Fullstack; pairs with api-collab. |
frontend-dashboard |
static + ssr |
Auth-gated app shell — a silent (marketing) route group + a /dashboard area gated by a nested layout loader that RedirectErrors to /login. Scoped error/loading/not-found. No backend. |
frontend-admin |
ssr · reactive |
Auto-admin back-office — discovers your api's entities at runtime (capability map) and renders a live, permission-gated <DataTable> + <AutoForm> per entity, with provenance + undo. Editable template code; pairs with any api. |
frontend-landing |
static · islands |
Marketing landing — hero, features grid, CTA. Zero JS by default; flip interactive: 'islands' for interactive pieces. |
frontend-docs |
static (catch-all SSG) |
Documentation site — catch-all docs/[...slug].tsx, per-section layout, getStaticPaths so every page pre-renders at build. |
frontend-i18n |
static · per-locale SSG |
Bilingual (en/de) URL-prefix i18n — type-checked catalogs, [locale] mirror pages, per-locale <title>. Each language is its own crawlable URL. |
changelog |
static |
Changelog / release-notes — MDX releases rendered to a list + per-release pages (highlighted code) + an RSS feed, powered by @voltro/changelog. |
frontend-static-blog |
static + islands |
SSG from a content source: dynamic [slug] routes pre-rendered via getStaticPaths, per-post meta from loader data, and ONE island (reading-progress bar) showing selective hydration. |
frontend-spa |
spa |
A pure client-rendered tool — state lives in the browser (localStorage), so there's nothing to SSR. Where a single-page app is the right call. |
frontend-ssr |
ssr + isr |
Server-rendered pages: a per-request SSR page (useServerRequest() for cookies/headers) + ISR pages (revalidate, staleWhileRevalidate, tenant-aware caching). Needs a runtime, not a CDN. |
frontend-ssr-api |
ssr · fed by api |
SSR from your backend — an ssr loader calls query('notes.list', {}) over the sibling api's POST /rpc, so real rows are in the first paint + <title>; useSubscription upgrades to live. Pairs with api-backend. |
frontend-contact |
static + serverless |
Static page + a serverless email form — the headline "static frontend, serverless backend" combo. The page ships to a CDN; the function scales to zero. |
Every one of these is kind: 'web', and again there are more web ids than rows here. The CLI rejects an api template passed to --web (and vice-versa) on a kind mismatch.
Serverless template (--template=<id> via add-app)
| Template | Best for |
|---|---|
edge-functions |
A library of *.serverless.ts functions covering the range of edge work — pure compute, request-header/geo, outbound HTTP (fire-and-forget + fetch-and-transform), Web Crypto HMAC verify, an LLM call, and status-controlled errors. Run with voltro serverless dev; ship to node / Cloudflare / Scaleway. No long-running server, no port. |
kind: 'serverless' — added to a project with voltro add-app <name> --template=edge-functions.
Mobile template (--mobile)
| Template | Best for |
|---|---|
mobile-app |
An Expo (React Native) app — the third consumer of your api, with the same typed hooks, offline-first defaults, typed deep links, and device registration for push. |
kind: 'mobile' — scaffold with voltro create-project <name> --mobile or voltro add-app <name> --template=mobile-app. A mobile app gets no port and is not run by voltro dev: Expo owns Metro (expo start / expo run:ios), and the app connects to the sibling api over the network. Its pure logic is unit-tested; the on-device reactive loop depends on the mobile plan's M0 (see React Native & mobile).
Static + serverless combo
The most common no-always-on-server shape: a static page on a CDN + a serverless function for the one dynamic bit. frontend-contact ships it whole — a static page whose island form POSTs to a bundled *.serverless.ts that sends mail. Or add edge-functions to any static web template and wire the page to whichever function it needs. The function's local dev server sends CORS headers (same as the edge hosts), so the cross-origin form works out of the box.
Baselines — the deploy layer
A baseline is orthogonal to the app template: it's the deploy/ops files that say how to run + ship the stack. Pick one at create time with --baseline=<id>, or switch later with voltro baseline set <id>. Four ship:
| Baseline | What it gives you | When to pick it |
|---|---|---|
bare |
.env.example + a sample systemd unit. No Docker, no Helm — you bring your own Postgres. |
Solo dev, prototyping, environments where Docker is unavailable. |
compose |
docker/{api,web}.Dockerfile + docker-compose.yml (Postgres) + dev (HMR) and prod (built images) variants. |
Teams without k8s, VPS/self-host, reproducible onboarding. |
compose-mariadb |
Like compose but MariaDB (binlog CDC, ROW) + MinIO object storage. The local mirror of the helm MariaDB shape. |
Apps targeting MariaDB + CDC + file storage locally. |
helm |
charts/voltro-app/ Helm chart, per-env values (dev/staging/prod), Deployment + Service + Ingress, Postgres StatefulSet OR external MariaDB via a db.dialect switch. |
k8s shops, GitOps (ArgoCD / Flux), multi-cluster prod. |
# Pick the app templates AND the baseline at once:
voltro create-project acme --api=api-backend --web=frontend-blank --baseline=compose
# Wire the Redis cache backend while scaffolding (injects the service into the baseline + .env):
voltro create-project acme --api=api-backend --web=frontend-blank --baseline=compose --cache=redis
# Switch the baseline later (destructive but backed up):
voltro baseline set helmWithout --baseline, the interactive prompt lists the ids; press Enter to skip and add one later. Baseline files apply at the workspace root (where pnpm-workspace.yaml lives), not inside apps/<project>/.
Where to read next
- App templates reference — the full catalogue table, by kind, with combos.
- Roll your own template — add a template the CLI scaffolds from.
- Scaffolding CLI — the commands that consume templates.