Your First App
- Scaffold a project
- Look around
- Create the database
- Serve it
- See every route
- Iterate with
xr dev - Generate something
- Next
Scaffold a project
From anywhere - every Larust crate is published to crates.io, so xr new
needs no checkout nearby by default:
xr new blog-tutorial --auth
A few things about that command:
- No workspace checkout required. The generated
Cargo.tomldepends on the publishedlarust-*crates directly (version = "..."), not a local path -xr newworks the same whether you’re inside a cloned Larust checkout or in a completely unrelated directory. Scaffolding inside your checkout underexamples/is still convenient if you’re actively developing Larust itself and want your test app to build against local, uncommitted framework changes instead of the published version - add--workspace <path-to-the-checkout>for that, and note the workspace root’s ownCargo.tomlalready listsexamples/*as a member glob, so an app scaffolded there needs no extra configuration to be picked up bycargo build --workspacefrom the checkout root. - Omit the path (
xr newwith nothing else) to get an interactive wizard instead - it asks for the project directory, whether to include auth, and which optionallarust-supportfeatures you want (see Optional Features for the full, current list), one at a time, rather than requiring you to already know every flag. --authscaffolds aUsermodel plus register/login/logout, so you get a real authenticated flow to look at rather than an empty shell. Leave it off for a minimal app with no auth at all.
You’ll see:
Created new Larust application at blog-tutorial
Look around
cd blog-tutorial
A --auth scaffold ships a small working blog: Post/Comment/User
models, a PostController with the full create/show/edit flow, real
register/login/logout routes, and Blade-flavored templates for all
of it. See Project Structure for what every file is.
Create the database
cargo run -- migrate
Migrated: 0001_create_posts_table.sql
Migrated: 0002_create_users_table.sql
Migrated: 0003_create_comments_table.sql
This runs every .sql file under database/migrations/ in order against
a fresh SQLite database (the default DB_CONNECTION) at the path your
.env names - no separate database server to install or configure for
local dev. See Migrations & the Query Builder
for MySQL/Postgres/SQL Server instead.
Serve it
cargo run
Or, if you have xr installed (see Iterate with xr dev), you can run it with:
xr dev
Visit http://127.0.0.1:34187 (Larust’s default APP_PORT - not 8000,
deliberately; see the FAQ). Register an account, write a post,
and you’re looking at a real, working Larust app.
See every route
From another terminal, in the same directory:
xr route:list
GET /
GET /posts posts.index
GET /posts/{post} posts.show
GET /__larust_wire/runtime.js
POST /__larust_wire/{component_id}
GET /__larust_spa/runtime.js
GET /__larust_reverb/runtime.js
GET /__larust_reverb/{channel}
GET /posts/create posts.create
POST /posts posts.store
POST /posts/{post}/comments posts.comments.store
GET /register register
POST /register register.store
GET /login login
POST /login login.store
POST /logout logout
The unnamed /__larust_* routes are framework-internal - the wire
component runtime script and its action endpoint, the SPA-mode runtime
script, and the live-broadcast WebSocket runtime/endpoint. They’re always
registered; you’ll never call them directly.
Iterate with xr dev
Stop cargo run and use the dev server instead:
../../target/debug/xr.exe dev # or just `xr dev` if it's on PATH
xr dev binds the port itself immediately (serving a “building…” page
if the very first build hasn’t finished yet), then rebuilds and hot-swaps
the running process on every save - with zero dropped requests, not
just a fast restart - and pushes a live-reload signal to any open browser
tab over SSE so it refreshes automatically once the new build is ready. A
build that fails leaves the last known-good version running and shows you
the real compiler error on the page, instead of taking the site down.
Each rebuild is a plain cargo build, not a from-scratch recompile - it
gets Cargo’s own incremental compilation for free, the same as running
cargo build by hand twice in a row. Editing your own app code (a
controller, a route, a template) only recompiles your app’s one crate,
typically a few seconds to under a minute depending on the app; the much
longer first build (and any rebuild after editing a framework crate
itself, if you’re working on Larust’s own source) recompiles the full
dependency tree instead, since that’s genuinely what changed. There’s no
separate “hot reload without recompiling” mode - Rust doesn’t support
patching a running compiled binary, so the fastest possible loop for
changed app code is exactly what happens today: recompile that one
crate, then swap the process with zero dropped requests.
Generate something
xr make:controller CommentController --resource
xr make:model Category --migration
xr make:policy Category
See the CLI reference for every make:* generator and
every other subcommand.
Next
Project Structure walks through what every generated file does, or jump straight into The Basics to start building.