# Rust off Rails > The opinionated web stack for the AI era: a set of Markdown files that tell coding agents how to build a full-stack Rust web app (Axum, SeaORM on SQLite and Postgres, htmx or Inertia, a database-backed job queue). The convention lives in the prose; the agent writes the code. Framework version 0.7.3. Install: `curl -fsSL https://rustoffrails.org/install.sh | sh`. In Claude Code: `/plugin marketplace add rust-off-rails/rustoffrails`, then `/plugin install offrails@offrails`. Any other agent: read `AGENTS.md` (below) and follow its load order. Every page below is plain Markdown. ## Start - [Get started](https://rustoffrails.org/start.md): from zero to a running app: install, the interview, the first feature, shipping - [Try it: prompt gallery](https://rustoffrails.org/prompts): ready-made app prompts for Claude Code and any AGENTS.md agent - [MCP server](https://rustoffrails.org/mcp): a hosted, read-only MCP server (Streamable HTTP, no auth) with search_docs, read_doc, rails_map, list_skills, starter_prompt, stack_versions, framework_info, upgrade_path, diff_doc, get_release, list_parts, read_part, list_snippets and read_snippet; setup for Claude Code, Claude, Cursor, ChatGPT and Codex - [Install script](https://rustoffrails.org/install.sh): the one-line installer (POSIX sh; supports --dry-run) ## Guide - [Guide](https://rustoffrails.org/guide.md): day to day: your role and the agent's, the loop, the Definition of Done, skills, guardrails, modes, upgrades - [Upgrading your app](https://rustoffrails.org/guide.md): section 6: `offrails update`, `offrails upgrade --check` and `offrails upgrade` (framework 0.4.0+), what the agent does, rules of thumb - [FAQ](https://rustoffrails.org/faq.md): agents and models, contributing and the code policy, cost, upgrades, security, production - [Tour: the dev tools](https://rustoffrails.org/tour): the dev dashboard (traces, hot functions), the dev mailbox, the jobs dashboard, live updates, channels and presence, and the JSON agents read ## Field tests - [Field tests](https://rustoffrails.org/field-tests.md): real open-source apps (Fizzy, FreeScout, Uptime Kuma) ported to the framework by agents: status, models, posts ## Philosophy - [The doctrine](https://rustoffrails.org/philosophy.md): the principles, led by §0: all code is written by AI ## Docs - [README: overview](https://rustoffrails.org/docs.md): The opinionated web stack for the AI era. - [Installing Rust off Rails](https://rustoffrails.org/docs/install.md): Read before you pipe: install.sh is about 300 lines of POSIX shell. Run it with --dry-run to print the plan and every command without changing anything. Here's… - [AGENTS.md: Rust off Rails](https://rustoffrails.org/docs/agents.md): You are building (or maintaining) a Rust off Rails application. This file is your entry point. It is written for you, the agent, not for humans. - [Cheatsheet](https://rustoffrails.org/docs/cheatsheet.md): The rules agents need most, on two pages. Read this first; open a full guide only when your task touches its topic (AGENTS.md maps topics to guides). When this… - [The Interview: asking the right questions](https://rustoffrails.org/docs/interview.md): Rails asked its questions through rails new flags. Off Rails asks them in conversation. Good questions are the difference between building the right app and… - [The Off Rails Doctrine](https://rustoffrails.org/docs/doctrine.md): The Rails Doctrine assumed a human at the keyboard. We kept its pillars and rewrote each one for an agent. - [Structure & Naming](https://rustoffrails.org/docs/structure.md): Every Off Rails app has this exact layout. Don't add top-level directories. Don't move things. Directories marked with a mode exist only in that mode. - [The Stack (the "Gemfile")](https://rustoffrails.org/docs/stack.md): One crate per job. Add each one with cargo add (and JS packages with pnpm add). Never write version numbers from memory. - [Agent Workflow](https://rustoffrails.org/docs/workflow.md): Humans describe the app in product/README.md and product/features/*.md (template: blueprints/feature-spec.md). They can also just talk to you. When they do… - [CLI: the app binary is bin/rails](https://rustoffrails.org/docs/cli.md): Every app compiles to one binary with clap subcommands. The binary is named after the crate. These docs call it app. - [Contributing](https://rustoffrails.org/docs/contributing.md): Rust off Rails has one founding rule: all code is written by AI (doctrine §0). That applies to this repository too. Contributions are intent and evidence, not… - [Security policy](https://rustoffrails.org/docs/security.md): Security is Rust off Rails' gold standard. The framework tells agents to build apps with strict CSP and security headers, authorization on every route and… - [APIs: FRONTEND_MODE: api and the API axis](https://rustoffrails.org/docs/guides/api.md): TL;DR - [Authentication & Authorization](https://rustoffrails.org/docs/guides/auth.md): TL;DR - [Caching (Solid Cache / Rails.cache → kernel/cache.rs)](https://rustoffrails.org/docs/guides/caching.md): TL;DR - [Channels, Presence and the Hub (kernel/hub.rs + the Off Rails Wire protocol)](https://rustoffrails.org/docs/guides/channels.md): TL;DR - [Config, Environments & Secrets](https://rustoffrails.org/docs/guides/config.md): TL;DR - [Controllers (Action Controller → axum handlers)](https://rustoffrails.org/docs/guides/controllers.md): TL;DR - [Database: one codebase, SQLite and Postgres](https://rustoffrails.org/docs/guides/database.md): TL;DR - [Deployment](https://rustoffrails.org/docs/guides/deployment.md): TL;DR - [Dev Tools (/dev, a small Phoenix LiveDashboard)](https://rustoffrails.org/docs/guides/dev-tools.md): TL;DR - [Errors & Logging](https://rustoffrails.org/docs/guides/errors-and-logging.md): TL;DR - [Frontend: htmx mode (Hotwire → htmx)](https://rustoffrails.org/docs/guides/frontend-htmx.md): TL;DR - [Frontend: inertia mode (inertia-rails → kernel/inertia.rs)](https://rustoffrails.org/docs/guides/frontend-inertia.md): TL;DR - [Frontend: spa mode with React (SPA + JSON API)](https://rustoffrails.org/docs/guides/frontend-react.md): TL;DR - [Frontend: Svelte (UI_LIBRARY: svelte)](https://rustoffrails.org/docs/guides/frontend-svelte.md): TL;DR - [GraphQL (API: graphql | both)](https://rustoffrails.org/docs/guides/graphql.md): TL;DR - [Jobs Dashboard (Oban Web / Mission Control → /admin/jobs + app jobs)](https://rustoffrails.org/docs/guides/jobs-dashboard.md): TL;DR - [Jobs (Active Job + Solid Queue, done the Oban way → kernel/jobs/)](https://rustoffrails.org/docs/guides/jobs.md): TL;DR - [Mailers (Action Mailer → lettre + Askama, with Swoosh's dev mailbox)](https://rustoffrails.org/docs/guides/mailers.md): TL;DR - [Migrations (db/migrate → migration/ crate)](https://rustoffrails.org/docs/guides/migrations.md): TL;DR - [Models (Active Record → SeaORM)](https://rustoffrails.org/docs/guides/models.md): TL;DR - [Realtime (Action Cable / Turbo Streams → signals over SSE)](https://rustoffrails.org/docs/guides/realtime.md): Status: a specification, not shipped code. Nothing in template/app or in the parts implements the pubsub module, the /streams/{stream} SSE route, the ?since=… - [Routing (config/routes.rb → src/routes.rs)](https://rustoffrails.org/docs/guides/routing.md): TL;DR - [Samples and parts: tested code for the parts most apps need](https://rustoffrails.org/docs/guides/samples.md): TL;DR - [Security](https://rustoffrails.org/docs/guides/security.md): TL;DR - [Storage (Active Storage → object_store + blobs)](https://rustoffrails.org/docs/guides/storage.md): TL;DR - [Test Standards: what every app must prove](https://rustoffrails.org/docs/guides/test-standards.md): TL;DR - [Testing](https://rustoffrails.org/docs/guides/testing.md): TL;DR - [Views (Action View → Askama)](https://rustoffrails.org/docs/guides/views.md): TL;DR - [Generators (rails generate → cargo offrails generate)](https://rustoffrails.org/docs/generators/readme.md): TL;DR - [Generator: new (rails new)](https://rustoffrails.org/docs/generators/new.md): TL;DR - [Generator: api (a public, versioned JSON API)](https://rustoffrails.org/docs/generators/api.md): TL;DR - [Accounts (rails generate authentication / phx.gen.auth): the auth parts](https://rustoffrails.org/docs/generators/authentication.md): TL;DR - [Generator: channel (live updates, rooms, presence)](https://rustoffrails.org/docs/generators/channel.md): TL;DR - [Generators: controller and page (rails generate controller)](https://rustoffrails.org/docs/generators/controller.md): TL;DR - [Generator: job (rails generate job) and task](https://rustoffrails.org/docs/generators/job.md): TL;DR - [Generator: mailer (rails generate mailer)](https://rustoffrails.org/docs/generators/mailer.md): TL;DR - [Generator: migration (rails generate migration)](https://rustoffrails.org/docs/generators/migration.md): TL;DR - [Generator: resource (scaffold) / model](https://rustoffrails.org/docs/generators/scaffold.md): TL;DR - [Generator: upgrade (rails app:update)](https://rustoffrails.org/docs/generators/upgrade.md): TL;DR - [The app template](https://rustoffrails.org/docs/template/readme.md): TL;DR - [Snippets](https://rustoffrails.org/docs/template/snippets/readme.md): TL;DR ## Reference - [Parts](https://rustoffrails.org/parts.md): tested kernel code added with `cargo offrails add `: what each gives you and requires - [Part: auth-core](https://rustoffrails.org/parts/auth-core.md): Accounts and sessions every auth sample shares: users, database sessions with rotation and revocation, an account security page (devices, activity), re-auth… - [Part: auth-magic-link](https://rustoffrails.org/parts/auth-magic-link.md): Passwordless sign-in: an emailed link plus a 6-digit code (for phones that open links elsewhere), single-use, hashed, 15 minutes, bound to the asking browser… - [Part: auth-password](https://rustoffrails.org/parts/auth-password.md): Email + password: argon2id (OWASP parameters, rehash on sign-in), sign-up with email verification, sign-in with progressive per-account delays, reset by… - [Part: auth-totp](https://rustoffrails.org/parts/auth-totp.md): Two-factor authentication (TOTP, RFC 6238): enrol with a server-side QR code or setup key, confirm before enable, a code step after any sign-in method, replay… - [Part: dev-dashboard](https://rustoffrails.org/parts/dev-dashboard.md): /dev/dashboard, an in-process LiveDashboard: live charts (memory, CPU, req/s, p50/p95/p99, errors, DB pool, Tokio), requests per route, traces as waterfalls… - [Part: dev-mailbox](https://rustoffrails.org/parts/dev-mailbox.md): A live local inbox at /dev/mailbox: HTML/text/raw/headers, width and dark previews, codes and links with copy, attachments, search, checks, previews, JSON and… - [Part: jobs](https://rustoffrails.org/parts/jobs.md): A DB-backed job queue (Oban-style): SKIP LOCKED / single-writer claims, typed args, retries with exponential backoff and jitter, unique jobs, priorities… - [Part: jobs-dashboard](https://rustoffrails.org/parts/jobs-dashboard.md): /admin/jobs: live overview (state counters, throughput and queue-wait charts, now-running lane with progress, queues with pause/resume, worker success rates… - [Part: mailer](https://rustoffrails.org/parts/mailer.md): Mailer: templated HTML + text email, delivery adapters (SMTP, dev mailbox storage, log, memory), previews, a test email task - [Part: realtime](https://rustoffrails.org/parts/realtime.md): Channels over WebSocket (offrails.v1) with SSE and long-poll fallbacks: typed rooms, topic authorization on every join and push, presence across tabs and… - [Snippets](https://rustoffrails.org/snippets.md): small tested code to copy: `cargo offrails snippet show|add|remove ` - [Snippet: atom-feed](https://rustoffrails.org/snippets/atom-feed.md): GET /feed.xml: an Atom feed (escaped, RFC 3339 dates, newest 20), linked from every page - [Snippet: markdown](https://rustoffrails.org/snippets/markdown.md): markdown::to_html: CommonMark (tables, strikethrough) rendered by pulldown-cmark, sanitized by ammonia - [Snippet: pagination](https://rustoffrails.org/snippets/pagination.md): PageLinks::new(base, page, more) and shared/_pager.html: the kit's pagination, per kept, ?page clamped - [Snippet: public-show-by-slug](https://rustoffrails.org/snippets/public-show-by-slug.md): GET /read/notes/{slug}: a public page per record, by slug (a path param), slugs unique and stable - [Snippet: resource](https://rustoffrails.org/snippets/resource.md): htmx CRUD for one model (notes: title, body): the files `g resource` writes, split per action, public - [Snippet: seed-backdated](https://rustoffrails.org/snippets/seed-backdated.md): Seeds with history: create through the model, then backdate::(db, id, days_ago(30)) moves the timestamps - [Snippet: slug](https://rustoffrails.org/snippets/slug.md): slugify(title) (accents folded, 80 chars) and unique(base, query): -2, -3… unique per owner or global - [Snippet: theme-toggle](https://rustoffrails.org/snippets/theme-toggle.md): A System/Light/Dark button in the nav: shared/_theme_toggle.html, a delegated handler in app.js, no-JS POST ## Optional - [Changelog](https://rustoffrails.org/changelog.md): every release and its app-migration notes - [Rails → Off Rails Map](https://rustoffrails.org/docs/rails-map.md): When a human (or your training data) says "the Rails way", look it up here. - [Contributor Covenant Code of Conduct](https://rustoffrails.org/docs/code-of-conduct.md): We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size… - [AGENTS.md](https://rustoffrails.org/docs/blueprints/agents.md): Each line is a mistake an agent shipped. The check that catches it is in parentheses. - [Decisions](https://rustoffrails.org/docs/blueprints/decisions.md) - [Feature: {{name}}](https://rustoffrails.org/docs/blueprints/feature-spec.md): {{The user problem this solves.}} - [{{App Name}}](https://rustoffrails.org/docs/blueprints/product-readme.md): {{One or two sentences: what the app does, for whom.}} - [Upgrade recipe (generators/upgrade.md)](https://github.com/rust-off-rails/rustoffrails/blob/main/generators/upgrade.md): the agent-neutral upgrade steps any agent can follow - [Everything in one file](https://rustoffrails.org/llms-full.txt): every doc above, concatenated