Get started
From zero to a running app.
One install line, one line describing your app, a short interview. The agent writes every line of code and stops only when the tests are green. Most of the wait is the first compile.
Install
One line, on macOS or Linux:
curl -fsSL https://rustoffrails.org/install.sh | sh- Rust, if
cargois missing: it asks first, then runs the official rustup installer. It never uses sudo. - The cargo tools the framework uses:
sea-orm-cli,cargo-nextest,cargo-watch, only the missing ones. - The framework, from the GitHub release, SHA-256 verified, in
~/.offrails/, plus theoffrailscommand. - The Claude Code plugin, if
claudeis on your PATH. For other agents, it prints the one-line prompt. - Docker, Node and pnpm are only detected, never installed. No telemetry.
Read before you pipe? Read the install script and INSTALL.md, or print the plan without changing anything:
curl -fsSL https://rustoffrails.org/install.sh | sh -s -- --dry-runAlready in Claude Code?
Install just the plugin, once per machine:
/plugin marketplace add rust-off-rails/rustoffrails
/plugin install offrails@offrailsThat adds nine skills, from /offrails:new to /offrails:upgrade, and the guardrail hooks. Both do nothing outside a Rust off Rails app. Using Codex or Cursor? See without Claude Code.
What you need
The installer takes care of the first two and tells you about the rest. To set up by hand, or to see what you're getting:
-
Rust, stable required
Installed with rustup, from rustup.rs:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -
Three cargo tools required
Migrations, the test runner, and rebuild-on-save.
bin/setupinstalls any that are missing, but doing it now saves a wait later.cargo install --locked sea-orm-cli cargo-nextest cargo-watch -
Docker optional
For running the tests on Postgres locally, running the whole app with
docker compose, and deploying. Without it, everything still runs on SQLite, and CI runs the Postgres tests for you. -
Node 24 LTS and pnpm only for a JS UI
Only for the
inertiaorspamodes, or htmx with islands. The default, htmx, needs no Node at all. pnpm comes with Node through corepack:corepack enable pnpm -
A coding agent required
Claude Code (recommended: the plugin adds the skills and guardrails below). Or Codex, Cursor, or any agent that reads
AGENTS.md: see without Claude Code.
Your first app
Start Claude Code in an empty directory:
mkdir bookshelf && cd bookshelf
claudeThen describe the app in one line:
/offrails:new bookshelf: people track books they've readOr from any terminal, with the offrails command the installer added (it starts Claude Code, or Codex, or prints the prompt for your agent):
offrails new bookshelf "people track the books they've read"-
The interview
Product questions only, at most three rounds, each with a recommended default listed first. It never asks which ORM or where files go: the framework already decided. Answer with a letter, in your own words, or with "you decide" to take the defaults.
-
The plan
A compact plan: resources, pages, jobs, and everything it assumed. Nothing is generated until you say yes. Change anything by saying so.
-
Generation
Your answers go into
product/specs and the app'sAGENTS.md. Then the app: migrations, models, controllers, templates, tests, a Dockerfile,compose.yamland CI, one vertical slice at a time. -
Green on both databases
It isn't done until the Definition of Done passes: fmt, clippy, and the whole test suite on SQLite and Postgres.
- > /offrails:new bookshelf: people track books they've read
- ● Reading the framework: interview · doctrine · structure · stack · workflow
- ? Accounts? a) Magic link (Recommended) b) Email + password c) Invite-only d) None
- › a
- ? Who owns data? a) Each user owns their records (Recommended) b) Teams c) Shared
- › you decide
- ? Frontend? a) htmx (Recommended) b) inertia c) spa d) api
- › you decide
- ◆ Plan: frontend htmx · Postgres in prod (SQLite locally) · deploy later
- Accounts magic link; each user owns their books
- Book title, author, finished_on (date), rating (1–5), belongs to User
- Pages books index/show/new/edit
- › yes
- + product/README.md · product/features/books.md · AGENTS.md
- + src/models/book.rs · src/controllers/books.rs · templates/books/
- + Dockerfile · compose.yaml · .github/workflows/ci.yml (+ many more)
- ✓ cargo clippy --all-targets -- -D warnings
- ✓ cargo nextest run · SQLite · all passed
- ✓ cargo nextest run · Postgres · all passed
- Definition of Done: green. Run
bin/setup && bin/dev
Run it
bin/setup && bin/devbin/setup creates .env, builds the CSS, compiles, and migrates and seeds the development database. bin/dev prints the URL to open: https://localhost:3000 (HTTP/2) when mkcert is installed, otherwise http://localhost:3000 with a note saying why (framework 0.6.1+; never a self-signed certificate, because browsers drop login cookies on it). It rebuilds, migrates and reloads open tabs whenever the agent changes something.
What you get on day one
-
/devDev tools: live tiles for the mailbox and jobs, routes, system info, pending migrations, and buttons to send a test email or enqueue a test job.
-
/dev/mailboxThe dev mailbox. Every email the app sends in development lands here, rendered, plus mailer previews. Nothing leaves your machine.
-
/admin/jobsThe jobs dashboard: states, retries, cron, queues. It runs in production too, behind admin access.
-
Docker
docker compose up --buildruns the production image against Postgres, on your laptop. -
CI
.github/workflows/ci.yml: the tests on SQLite and Postgres, and the Docker build, on every push. -
/upA health check for load balancers and deploys: 200 when the app is up, 503 while migrations are pending.
Your first feature
Two ways in. Both end in the same place: a spec in product/features/, then code, then green.
A Say it
/offrails:feature let people review books; email the ownerThe agent asks only what changes the build (who can review? can a review be edited? can owners opt out of the email?), then writes the spec for you to read.
B Write it
Plain English in product/features/reviews.md. Any part is fine; the agent fills the gaps and marks what it assumed.
# Feature: Reviews
## Why
Readers want to know what others thought of a book.
## Behavior
- A logged-in user can review a book once: 1–5 stars and a few lines.
- The book's owner gets an email for each new review.Then:
/offrails:featureWith no argument it builds whatever changed in product/.
For anything bigger than one slice, it shows the plan and waits for a yes. Then it builds migration → model → failing tests → code, ticks each acceptance criterion once its test passes on both databases, and tells you what changed in product terms. What a full spec looks like.
Ship it
/offrails:deploy kamalPick a target: Kamal (your own server), Fly.io, Render or Railway. With no target it uses the one from the interview, or asks.
It writes the Dockerfile and the target's config, runs the Definition of Done, builds the image and checks /up locally. Then it stops and confirms before anything outward-facing: the exact commands, what each one costs or changes, and which secrets you supply. Nothing runs without your yes. Migrations run on every boot.
Upgrading your app
Each app keeps its own pinned copy of the framework in .offrails/, so nothing changes until you upgrade. Commit first. Then get the latest release:
offrails updateSee whether your app is behind (it compares content, not just version numbers): framework 0.4.0+
cd my-app && offrails upgrade --checkAnd upgrade: framework 0.4.0+
offrails upgradeIt starts your agent with the upgrade recipe: Claude Code runs /offrails:upgrade, opencode and Codex get the recipe automatically, and for any other agent it prints a prompt to paste. The agent shows you a plan before changing anything.
On a release before 0.4.0, run offrails update, then ask your agent, in the app:
Upgrade this Rust off Rails app to the framework in ~/.offrails/current, following https://github.com/rust-off-rails/rustoffrails/blob/main/generators/upgrade.md step by step. Reconcile, don't re-create; never edit applied migrations. Start from a clean git tree, show me the plan before changing anything, and finish with the Definition of Done on SQLite and Postgres.Several releases behind? Upgrade one release at a time. What the agent does during an upgrade.
Without Claude Code
The framework is Markdown, so any agent that reads AGENTS.md can use it: Codex, Cursor, and others. Clone the framework repository, then tell your agent:
Read /path/to/rustoffrails/AGENTS.md and make me a new app called "bookshelf".Every generated app carries its own AGENTS.md and a pinned copy of the framework in .offrails/, so later sessions need no setup. Without the plugin you don't get the slash commands or the hooks: ask in plain words ("add reviews to books", "run the Definition of Done").
Only want your agent to read the docs, with nothing installed? Connect it to the hosted MCP server: Claude Code, Claude, Cursor, ChatGPT and Codex all work.
Troubleshooting
Is my machine set up right?
The installer's command prints a table of every prerequisite and its version:
offrails doctorRe-run the installer, or offrails update, to fill any gaps.
The first build is taking forever
Expected: a cold build of this stack takes about 10 minutes, and bin/setup says so. After that, rebuilds are incremental and take seconds.
The agent says the Postgres tests were skipped
It never claims Postgres passed when it couldn't run it. Start the app's Postgres container, then run the suite against it:
docker compose up -d db
TEST_DATABASE_URL=postgres://postgres:postgres@localhost:5432/postgres cargo nextest runNo Docker? CI runs the Postgres tests on every push.
Where are the logs?
- Requests and errors print to the terminal running
bin/dev, one span per request with its request id. Turn the detail up or down withRUST_LOGin.env. - Failed jobs:
/admin/jobs, or in a terminal:
cargo run -- jobs list --state discarded- Emails:
/dev/mailbox. Environment, database and migrations:/dev/system.
A page says migrations are pending
Press its Run migrations button, or run:
cargo run -- db migratePort 3000 is already taken
PORT=3001 bin/devSomething's red
Ask the agent to run the Definition of Done and fix what fails:
/offrails:checkIf the app has drifted from the conventions (say, after someone edited code by hand), /offrails:doctor audits it and /offrails:doctor --fix repairs it.