The day-to-day Suprnova loop is one command: suprnova serve. It runs
the Rust backend, the Vite frontend, and a TypeScript-types regenerator
in a single process, each watching the right files. This chapter covers
the dev server, how the hot-reload pieces fit together, and the
commands you'll reach for daily. For first-time setup see
Installation; for the directory tour see
Directory Structure.
The dev server
From a scaffolded project's root:
The CLI prints two URLs and then a continuous stream of prefixed output from each child process:
Backend http://127.0.0.1:8765
Frontend http://127.0.0.1:5765
[backend] Compiling links v0.1.0
[backend] Finished `dev` profile [unoptimized + debuginfo] target(s) in 4.21s
[backend] Running `target/debug/links`
[frontend] VITE v6.0.1 ready in 312 ms
[frontend] ➜ Local: http://localhost:5765/
[types] Watching for Rust file changes to regenerate types
You hit the backend URL (127.0.0.1:8765). Vite serves your JS/CSS
through Inertia's dev integration - you don't visit :5765 directly.
Press Ctrl+C once and the CLI shuts both children down cleanly.
Flags
| Flag | Default | What it does |
|---|---|---|
-p, --port <N> |
8765 |
Backend port |
--frontend-port <N> |
5765 |
Vite port |
--backend-only |
off | Skip the Vite child (API-only work) |
--frontend-only |
off | Skip the backend child (component work against a running backend elsewhere) |
--skip-types |
off | Skip the TypeScript-type generator + its watcher |
The same ports can be set in .env via SERVER_PORT and VITE_PORT.
A flag on the command line wins over .env.
What it pre-flights
Before spawning anything, suprnova serve:
- Checks you're in a project. Aborts with a clear error if there's
no
Cargo.toml(or nofrontend/when running the frontend). - Generates TypeScript types once. Scans
src/for#[derive(InertiaProps)]and writesfrontend/src/types/inertia-props.ts. Skipped by--skip-typesor--frontend-only. - Installs
cargo-watchif missing. First run on a new machine runscargo install cargo-watchfor you, then continues. - Runs
npm installiffrontend/node_modulesis missing. No manual install step on a fresh clone.
Hot reload
Three watchers run concurrently inside suprnova serve:
cargo watch -x 'run --bin <pkg>'drives the backend. Any.rschange under the project triggers a recompile and an in-process restart. Compile errors print to the[backend]stream and the previous binary stays up until the next successful build.- Vite drives the frontend. Component, style, and asset edits hot-module-replace into the open browser tab without a full reload.
notify-based type watcher reruns the InertiaProps scanner whenever a.rsfile changes. It debounces at 500ms so a burst of saves regeneratesinertia-props.tsonce. Output appears under the[types]prefix.
That third one is the bit you don't have to think about: rename a field
on a #[derive(InertiaProps)] struct and the matching TypeScript
interface follows on the next save. The Svelte/React/Vue page picks
the new type up immediately. No suprnova generate-types invocation
needed during normal dev.
Why Suprnova diverges
Most Rust web stacks make hot reload your problem - pick your own
file watcher, write your own restart wrapper, run Vite in a separate
terminal. Most Laravel stacks make TypeScript types your problem -
declare them in two places (PHP and TS) and keep them in sync.
suprnova serve runs both watchers, plus the type generator that
keeps your frontend types honest, as one supervised process. The
Tokio runtime makes "many things at once" cheap enough that a dev
loop can spend it freely.
Day-to-day commands
The handful you'll run hourly:
db:sync is the dev shortcut for "migration + entity regen in one
step." In production you use plain suprnova migrate because you
don't want regeneration to happen on a release box. The full generator
surface is in Code Generators and the migration
verbs are in Migrations.
Debugging
Logging
Suprnova uses tracing end-to-end. Filter what gets printed with
LOG_LEVEL (the same syntax as tracing-subscriber's EnvFilter):
# Verbose framework output
LOG_LEVEL=debug
# Quiet hyper but verbose your crate
LOG_LEVEL=info,my_app=debug,hyper=warn
Output format is controlled by LOG_FORMAT (pretty for human-readable,
json for machine-parseable). The dev default is pretty. See
Observability for the full logging surface.
SQL queries
Turn on per-query logging with one env var:
DB_LOGGING=true
This routes every SeaORM query through tracing at info so you can
see exactly what's executing. Leave it off in production unless you're
chasing a specific slow query - the volume gets noisy fast.
Backtraces
Standard Rust:
RUST_BACKTRACE=1
A panic in a handler is caught and turned into a structured 500 response; the backtrace lands in your logs without taking the server down. See Error Model for how that contract works.
Tests in the loop
Test execution is plain Cargo. The framework-side helpers
(#[suprnova_test], TestDatabase, expect!, fakes for Mail/Queue/
Storage/etc.) are documented in Testing and
Database Testing. They run under the same
cargo test you already know.
Working with the SSR worker
If your app uses Inertia server-side rendering, you'll want the SSR
worker alongside suprnova serve during dev:
# Terminal 1
# Terminal 2
ssr:start runs the bundled SSR worker under Node, Bun, or Deno
(--runtime). ssr:check verifies a running worker is reachable.
Both are documented under the frontend chapter - see
Frontend.
When something looks wrong
A short triage list for the most common dev-loop hiccups:
- Port already in use. Another
suprnova serveis still up, or a prior backend wedged.lsof -i :8765to find it, or just pass--port 8001. cargo-watchkeeps recompiling. Some editor is rewriting files on save (formatters, linters with autofix). Disable on-save format for the project, or scope your watcher withCARGO_WATCH_IGNOREpatterns.- TypeScript types not updating. Either
--skip-typeswas passed, or the watcher tripped over a.rsparse error. Look at the[types]lines - it prints a warning and continues rather than failing the whole serve. - Vite errors but the backend is fine. Run
npm installinfrontend/once (the CLI does this on first serve, but if you blow awaynode_modulesit won't redo it until that directory is missing again on a fresh start).
Anything else, the Errors chapter covers deeper triage patterns.
Next
- Installation - first-time setup of the CLI and a project
- Quickstart - build a tiny app end-to-end
- Directory Structure - what each directory holds
- Code Generators - every
make:*command - Testing -
#[suprnova_test], fakes, and the test database
