suprnova serve runs your backend and the Vite dev server together with hot
reload on both sides, plus automatic TypeScript type regeneration whenever you
touch a #[derive(InertiaProps)] struct. It's the one command you keep open
in a terminal while you're building.
Both processes stream their stdout into the same terminal with coloured
[backend] and [frontend] prefixes so you can tell who said what. Ctrl+C
shuts them both down cleanly.
Usage
| Option | Default | Description |
|---|---|---|
-p, --port <PORT> |
8765 (CLI) / $SERVER_PORT (env) |
Backend HTTP port |
--frontend-port <PORT> |
5765 (CLI) / $VITE_PORT (env) |
Vite dev server port |
--backend-only |
false |
Skip the Vite dev server |
--frontend-only |
false |
Skip the backend, just run Vite |
--skip-types |
false |
Don't regenerate TypeScript types on Rust changes |
The CLI flags take precedence over environment variables, which take precedence
over the built-in defaults. A scaffolded .env ships with SERVER_PORT=8765
and VITE_PORT=5765; you'll see those values used unless you override with
--port.
Examples
Default - both servers
Output:
Backend http://127.0.0.1:8765
Frontend http://127.0.0.1:5765
[backend] Compiling my-app v0.1.0 ...
[frontend] VITE v6.3.0 ready in 312 ms
Hit http://127.0.0.1:8765 in your browser. The backend serves the Inertia
HTML shell and proxies asset requests through to Vite, so you don't need to
visit the Vite URL directly.
Custom ports
Or set them in .env and run without flags:
SERVER_PORT=3000
VITE_PORT=3001
Backend only
Good for working on an API-only project, or when your frontend is already running in another terminal (or another machine, or a deployed preview).
Frontend only
Good for working on UI without paying the cost of a Rust rebuild on every save, or when the backend is running in another shell (or in Docker).
Skip type generation
Disables the TypeScript regeneration watcher. Use this when you're managing
frontend/src/types/inertia-props.ts by hand, or when you're working far
from any Inertia code and want quieter output.
What it actually does
When you run suprnova serve, the CLI:
- Loads
.envfrom the current directory. - Resolves backend and frontend ports (CLI flag → env var → default).
- Verifies you're in a Suprnova project -
Cargo.tomlmust exist (unless--frontend-only) and afrontend/directory must exist (unless--backend-only). - Regenerates TypeScript types from any
#[derive(InertiaProps)]structs it finds insrc/, writing them tofrontend/src/types/inertia-props.ts. - Installs
cargo-watchviacargo install --locked --version "^8.5" cargo-watchif it isn't on the PATH yet (one-time, with an "Installing..." notice). Skipped under--frontend-only. The version is bounded becauseservedrivescargo watch -x, whose meaning is not guaranteed across a major bump;--lockedbuilds the dependency tree cargo-watch published rather than re-resolving it at install time. A command that installs software as a side effect of starting a dev server should not also be choosing versions for you. - Runs
npm installinfrontend/ifnode_modulesdoesn't exist yet. Skipped under--backend-only. - Spawns
cargo watch -x 'run --bin <package-name>'for the backend.cargo-watchre-runs the binary whenever a.rsfile changes. - Spawns
npm run devinfrontend/for Vite, which gives you HMR for Svelte/React/Vue components and Tailwind classes. - Starts a file watcher on
src/that re-runs the type generator whenever a.rsfile changes, once the burst of saves has been quiet for 500 ms. The debounce is trailing-edge, so a burst -cargo fmt, format-on-save across several files, a branch switch - coalesces into exactly one regeneration that runs after the last write, rather than one that fires on the first file and misses the rest. - Forwards both children's stdout/stderr to your terminal with
[backend]and[frontend]prefixes.
Ctrl+C signals the manager to set its shutdown flag, kill both children,
and exit. If either process exits on its own - usually because of a Rust
compile error too severe for cargo watch to recover, or a port conflict -
the manager treats that as a shutdown signal and tears down the other.
Why Suprnova diverges
Laravel users typically run php artisan serve for the backend and npm run dev in another terminal, and most teams paper over the two-terminal
split with a Procfile and foreman/overmind. Suprnova ships that
multiplexer as a first-class CLI command. You get one terminal, one
Ctrl+C, automatic toolchain bootstrap (cargo-watch, npm install),
and a typed-Inertia bridge that regenerates frontend/src/types/inertia-props.ts
on the fly so your Svelte/React/Vue components always see the current
prop shape without manual type sync.
Hot reload
Backend. cargo watch -x 'run --bin <package>' is the loop. It rebuilds
and restarts the server on every .rs change in the project. Cold rebuilds
after touching a heavy crate can take several seconds; incremental changes
in a single file are usually sub-second.
Frontend. Vite's HMR injects component changes in place without a full reload, preserving component state. Tailwind classes update live via the Tailwind v4 watcher.
TypeScript types. Whenever a .rs file changes, the type watcher re-runs
the generator. If new #[derive(InertiaProps)] structs appear (or existing
ones change shape), the regenerated frontend/src/types/inertia-props.ts
triggers Vite's HMR for the component that imports them.
Troubleshooting
Port already in use
[backend] Error: Address already in use (os error 98)
Find and kill the process, or pick another port:
# or
cargo-watch install fails
The CLI runs cargo install cargo-watch if it isn't already on PATH. If
that install fails (no network, restricted environment), install it manually
once:
After that, suprnova serve will find it and won't try to install again.
Frontend dependencies stuck
If npm install fails mid-bootstrap, fix the cause (npm registry reachable,
disk space, lockfile in good shape) and run it manually:
&&
Then re-run suprnova serve. The CLI only auto-runs npm install when
node_modules is missing, so a successful manual install lets it skip that
step.
Type regeneration not picking up changes
The watcher polls every 2 seconds (using notify with a poll interval -
chosen for cross-platform reliability over inotify quirks) and debounces
regeneration to once every 500 ms. If a change isn't showing up:
- Confirm the file is under
src/(the watcher doesn't recurse intocrates/,cmd/, ormigrations/). - Confirm the struct actually has
#[derive(InertiaProps)]. - Restart
suprnova serveand watch for theGenerated N type(s)startup message - if you seeNo InertiaProps structs found, the scanner didn't find anything to emit.
Backend exits silently right after start
When either child process exits, the manager shuts the other down too. If
the backend died with a compile error, the [backend] lines just above
the "Servers stopped." message will show the error[E…] from rustc. Fix
the compile error and re-run.
Next
- Installation - get the CLI on your machine
- Quickstart - a full first-app walkthrough
- Directory Structure - what
suprnova newscaffolded - Generators -
make:controller,make:action, etc. - Console - the per-project
cargo run --bin consolebinary
