Your first app
Start a small writing app by creating Maya's account. You'll define a User model,
generate its Rust client, create the database, and save and read back your first user.
Later tutorials add Maya's posts and conversations with Ken, one capability at a time.
This walkthrough uses SQLite so you can get running without setting up a database server. The same schema and client workflow applies to PostgreSQL, MySQL, and MariaDB.
Before you begin
Follow installation to set up Rust and the Rent CLI. Rent is available through private preview.
Create an application
Create a new SQLite application:
rent new social-app --database sqlite
cd social-apprent new creates a two-crate workspace: social-app, where your code goes, and social-app-db, which owns
the starter User entity, the generated client, and the migration directory. It also writes rent.toml,
formatter settings, a local .env containing DATABASE_URL, and a dependency pinned to the installed CLI's Rent revision.
Rent loads that project .env automatically. Keeping the client in its own crate means an edit to your code
never recompiles the generated client.
Check the complete project before changing the database:
rent doctorRent Doctor
Ready Configuration ./rent.toml
Ready Cargo project
Ready Schema 1 entity
Ready Client generated and current
Ready Module declared in the crate root
Ready Layout generated client in its own crate, social-app-db
Ready Migrations no migration history yet
Ready Database sqlite connection verified
Healthy: Rent project is healthy.Create the database schema
Turn the starter RSL model into the first migration and apply it:
rent migrate dev --name initialmigrate dev performs a complete local feedback loop. It inspects the database, plans the difference, writes a
checksummed SQL migration, applies pending migrations, and inspects again to prove the database now matches the
RSL schema.
Migration: initial
Created ./social-app-db/rent/migrations/20260910023750_initial.sql (1 change)
Applied 20260910023750_initial (1 statement)
Verified: Database matches the RSL schema.Compile and run the generated application:
cargo check
cargo runRent connectedAt this point the complete path works: RSL schema → generated Rust client → reviewed migration → live database → async application.
Understand the generated project
The files you will work with most often are:
| Path | What it does | How to treat it |
|---|---|---|
rent.toml | Configures the schema, generated code, migration, and extension manifest paths and the development database | Edit and commit |
social-app-db/rent/schema.rsl | Defines models, fields, relationships, indexes, and database objects | Edit and commit |
social-app-db/rent/generated/ | Contains schema-specific models and client builders, declared in social-app-db/src/lib.rs | Regenerate and commit. Do not hand-edit |
social-app-db/rent/migrations/*.sql | Stores append-only schema and authored data migrations | Review and commit |
social-app-db/rent/migrations/rent.sum | Protects migration history with checksums | Update through Rent commands and commit |
social-app/src/main.rs | Connects the generated client to application code | Edit as ordinary Rust |
Code generation and migration planning both read the same social-app-db/rent/schema.rsl source of truth.
Make your first schema change
Open social-app-db/rent/schema.rsl and expand the starter model:
model User {
id BigInt @id @default(autoincrement())
email String @unique
name String
version UInt @rent.version
}Inspect Rent's interpretation, rebuild the client, and migrate the development database:
rent describe
rent generate
rent migrate preflight
rent migrate dev --name add_user_profileUse rent dev in another terminal when you want generation to follow schema edits automatically.
Use the typed client
The generated client accepts borrowed strings and exposes methods derived from the schema:
let maya = client
.create_user()
.email("maya@example.com")
.name("Maya")
.save()
.await?;
let same_user = client
.user()
.email_eq("maya@example.com")
.only()
.await?;only() returns one row or a typed cardinality error. Use only_or_none(), all(), count(), projections, pages, or
bounded streams when the expected result shape differs.
The generated application connects from DATABASE_URL:
let database_url = std::env::var("DATABASE_URL")?;
let client = generated::client::Client::connect(&database_url).await?;Use Client::connect_with when the application needs custom pool limits, acquisition timeouts, or connection
lifetime settings.
Browse the result
Open the development database in Rent Studio:
rent studioStudio opens a loopback-only web interface and is read-only by default. Press Ctrl+C in its terminal to stop it.
Your everyday loop
Once the project is established, most schema work follows this sequence:
rent describe
rent generate
rent migrate preflight
rent migrate dev --name describe_the_change
cargo nextest runUse rent doctor whenever configuration, generated code, migrations, Cargo features, or database connectivity seem
inconsistent.
Choose what to learn next
You now have a running application. Continue building with the step-by-step tutorials, or choose a guide for a particular task.
Before shipping, work through application testing, then production deployment.
