Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Supervised Development Auto-Reload

Release-audit follow-up: the implementation and final workspace validation are still in progress. See the audit evidence; this tutorial is not a claim that the current branch is already release-ready.

Rullst v12’s development command rebuilds and restarts a directly linked application. This keeps Tokio, ORM pools, sessions and other process globals in one runtime. It replaces the advertised DLL-swap profile after Windows/LMS testing exposed an uninitialized ORM in the loaded library.

Run the development loop

Generate a normal application and use either development command:

cargo rullst new learning-app --default --blueprint blank \
  --database sqlite --skip-initial-migration
cd learning-app
cargo rullst dev
# Or, in an interactive terminal:
cargo rullst dash

There is no hot-reload question in the v12 wizard. Both commands supervise reloads automatically; use cargo run for ordinary execution.

What a save does

flowchart LR
    A[Save source or assets] --> B[Coalesce changes]
    B --> C[Compile executable]
    C -->|Failure| D[Keep current application and show diagnostic]
    C -->|Success| E[Snapshot new executable]
    E -->|Failure| D
    E -->|Success| F[Stop owned child and start replacement]
    F --> G[Verify process generation over HTTP]
    G --> H[Browser refresh]

The watcher observes source, static assets, templates and manifest/configuration files, including atomic editor renames. It excludes build outputs, Git data and runtime database/log files. Events while a build is running remain pending for a later rebuild. Saving CSS also triggers this conservative rebuild/restart path; no compilation-free claim is made.

Initial migrations run before the first start when the generated migration directory exists. Later migrations are explicit: use the dashboard migration action or cargo rullst db:migrate. The dashboard queues migrations through the supervisor, using its current executable snapshot with bounded output and cancellation cleanup; the action is serialized with rebuilds. It does not compile an unsaved or unbuilt migration into that snapshot. Restarting a process does not apply arbitrary database-schema changes safely.

Failure and state boundaries

EventBehavior
Compiler errorKeep the current process running; retain bounded diagnostics.
Snapshot copy/create errorKeep the current process running and report the failure before stopping anything.
Successful buildSnapshot the executable, stop the owned child, start the replacement.
Replacement cannot spawnAttempt to restart the prior executable snapshot and report the error.
Replacement exits during startupReport the exit; save a correction to rebuild and retry.
Readiness cannot be verified in 15 secondsReport the limitation; do not claim successful readiness.
Dashboard exit / Ctrl+CCancel owned build/migration work and terminate/reap the application, subject to the Windows descendant limitation below.
Configured port changesRestart the CLI so its dashboard/readiness target follows the new port.

The old binary is copied before execution so Windows does not lock Cargo’s output during the next build. Cleanup targets only the snapshot created by this supervisor. On Unix the child receives a two-second shutdown interval, followed by termination of its owned process group if needed; group cleanup precedes reaping the leader. Windows uses best-effort tree termination: without Job Objects it cannot guarantee cleanup of orphan descendants after their parent has exited, and it does not promise graceful request drain.

All process-local state resets, including in-memory sessions/queues/caches. Persist important state explicitly. In-flight requests may be interrupted. This is a local development loop, not zero-downtime production deployment.

Browser and security boundary

The debug/development server serves a local reload script and an opaque generation marker under /_rullst/dev-*. The script polls the same origin and refreshes only after a different valid generation responds. Readiness checks match the child generation rather than trusting any service on the port. The marker is not a secret or an authentication credential. These endpoints cannot instruct the server to compile, launch a process, or swap a library.

Eligible full-document, known-size, uncompressed HTML up to 10 MiB receives the script and a nonce seeded before inner header middleware. HTMX partial requests, streaming/larger/compressed responses pass through without injection. A browser singleton prevents duplicate pollers, and changed HTML is marked no-store. Polling has a request timeout and bounded retry delay. Browser refresh loses unsaved DOM-only state. Custom routers that do not use the Rullst Server development composition may need manual browser refresh.

Production/release builds do not mount this browser surface. Keep development servers on loopback and do not override their host for an untrusted network. The current supervisor probes 127.0.0.1 and the configured port; custom HOST or RULLST_HOST bindings, including IPv6-only loopback, are not equivalent verified-readiness configurations. Keep the default host and restart the CLI after changing its port configuration.

Existing DLL scaffolds and the v13 decision

The v12 CLI rejects the old --hot-reload generation flag and removes HOT_RELOAD when it launches a child, so old generated projects use their directly linked router unless their application reloads that variable itself. Remove legacy HOT_RELOAD entries from .env as well: application-owned dotenv loading can otherwise restore them. Regenerate fresh projects for release acceptance; already edited application code may need application-specific migration.

The existing library loader is retained only as a legacy experimental boundary. Passing Rust, Axum, Tokio or SQLx objects across a library ABI does not provide a stable interoperability contract. Do not reintroduce cross-library ORM pools.

For v13, compare supervised restart with any proposed replacement using real blueprints and databases on Windows, Linux and macOS. Measure cold/warm reload time, failed-build recovery, cancellation, memory growth, process cleanup and state ownership. Restore DLL swapping only if its safety requirements can be established and it offers a measured practical benefit; keeping supervised restart remains a valid v13 outcome.

Terminal accessibility

Use RULLST_REDUCED_MOTION=1 cargo rullst dash for static rendering with colors, or NO_COLOR=1 cargo rullst dash for static color-free output. Use cargo rullst dev with redirected/non-interactive output.