Rails 8
Agent Skills that teach Claude to build Rails 8.1 apps — vanilla-first stack, pure RSpec, Hotwire (Turbo/Stimulus/Native), OpenAPI via rswag, ruby_llm AI, Kamal 2 deploys
npx -y skills add fmanimashaun/claude-skills --skill rails-8Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Playbook for building full-stack Ruby on Rails 8.1 applications "the Rails way" — vanilla Rails, Hotwire (Turbo + Stimulus), the Solid stack, Propshaft + importmap, RSpec testing, ecosystem gems, OpenAPI docs, AI features, observability, and Kamal 2 deployment. Use this skill whenever the user is creating, extending, debugging, refactoring, testing, upgrading, documenting, or deploying a Rails app — or mentions Ruby on Rails, a Gemfile containing rails, ERB templates, Active Record, migrations, Hotwire, Turbo, Stimulus, Action Mailer, Active Storage, Action Text, Action Cable, Solid Queue, Solid Cache, Kamal, Thruster, RSpec, FactoryBot, simple_form, Tailwind, OpenAPI, Swagger, rswag, ruby_llm, or `bin/rails` commands. Trigger it for indirect phrasings like "my Ruby web app", "add a background job", "make this page update live", "add login to my app", "document my API", or "add AI to my app" when the project is Rails. Also for "how should I structure this in Rails?" questions.
SKILL.md
14.5 KB, as published. Nobody here has run it
Rails 8 Full-Stack Development — The Rails Way
This skill encodes the officially recommended way to build Rails 8.1.x applications, distilled from the Rails Guides (v8.1.3) and the framework's own generated defaults. Follow it to produce code a Rails core contributor would recognize as idiomatic: the omakase menu, the one-person-framework, the majestic monolith.
Operating principles
- Convention over configuration. Before writing configuration, glue code,
or a new abstraction, check whether Rails already has a convention for it.
It almost always does. Naming alone (singular model
Order, tableorders, controllerOrdersController, partial_order.html.erb) wires most things together. - Vanilla Rails first. Rails 8 deliberately eliminated whole gem
categories — use the framework's answer, never a substitute: the built-in
authentication generator (not an auth engine), Solid Queue (not an
external job backend), Solid Cache/Cable (not Redis), Hotwire (not a JS
SPA), importmap (not a JS bundler), Kamal (not a PaaS). Deliberate
exception — testing: this skill standardizes on the industry RSpec stack
(rspec-rails, FactoryBot, Faker, Capybara, SimpleCov, WebMock/VCR, pure
RSpec matchers — see
references/testing.md); apps are scaffolded with--skip-testso the framework's default suite never exists in the repo. Project exception: dropped into an existing app that made different choices (another test framework, job backend, auth solution, a JS bundler, PostgreSQL…), follow the project, not this skill. Never mix two conventions for the same concern in one codebase. - Fat models are fine; skinny everything is a myth. Rails-way domain
logic lives in Active Record models, POROs under
app/models, and concerns. Do not introduce service-object layers, repositories, or hexagonal architecture unless the project already uses them. Controllers stay thin: translate HTTP to model calls, pick a response. - Server-rendered HTML is the default UI. Reach for Turbo Frames/Streams and small Stimulus controllers before any client-side framework. JSON APIs only when there is a genuine non-browser consumer.
- Compression of complexity. One command should do the setup work:
bin/setup,bin/dev,bin/ci,bin/rails db:prepare,kamal deploy. Keep those commands working.
Version facts (as of this skill's writing)
- Current stable: Rails 8.1.3 (2026-03-24). The 8.1 series receives bug fixes until October 2026, security fixes beyond. Rails 8.0 is security-fixes-only from May 2026.
- Requires Ruby >= 3.2. Prefer the latest stable Ruby (4.0.x, released Dec 2025; 3.4.x also fully supported). Keep YJIT for production; ZJIT is still experimental.
- New apps get
config.load_defaults 8.1inconfig/application.rb. - If the user's app is on an older Rails, upgrade one minor version at a time
(7.2 → 8.0 → 8.1) with
bin/rails app:updateand the framework-defaults file. Verify current versions with a web search if the date is well past March 2026.
What rails new gives you (the default stack)
| Concern | Default | Notes |
|---|---|---|
| Database | SQLite3 (production-ready) | --database=postgresql (or mysql/trilogy) for client-server DBs |
| Assets | Propshaft | No transpiling; digest-stamping only |
| JavaScript | importmap-rails + Hotwire (Turbo + Stimulus) | --javascript=bun/esbuild/webpack/rollup if bundling needed |
| CSS | Plain CSS | `--css=tailwind |
| Jobs / Cache / WebSockets | Solid Queue / Solid Cache / Solid Cable | Database-backed; no Redis |
| Web server | Puma, fronted by Thruster in Docker | Thruster: HTTP/2, TLS, compression, asset caching |
| Deployment | Kamal 2 + generated Dockerfile | config/deploy.yml, .kamal/secrets |
| Testing | RSpec + FactoryBot + Capybara (pure RSpec, no matcher add-ons) | Scaffold with --skip-test; doctrine in references/testing.md |
| Lint / security | rubocop-rails-omakase, Brakeman, bundler-audit | Wired into CI |
| CI | config/ci.rb + bin/ci (local CI, new in 8.1) and a GitHub Actions workflow | --skip-ci to omit |
| Extras | PWA stubs (app/views/pwa/), script/ for one-offs, /up health endpoint, Docker entrypoint running db:prepare |
The golden-path feature workflow
For "add X to my app" tasks, work in this order — it matches how Rails wants to be driven and keeps every step verifiable:
- Model + migration.
bin/rails g model Product name:string:index price_cents:integer(org migration AddStatusToOrders status:integer). Put constraints in the migration (null: false, defaults, FKs, unique indexes), validations + associations in the model. Runbin/rails db:migrate. - Routes. Add a
resources :productsline (nest at most one level; usemodule:/namespacefor admin areas). - Controller. Seven RESTful actions max; more verbs mean a new resource,
not a custom action. Use
params.expect(product: [:name, :price_cents])for strong parameters (8.x idiom). - Views. ERB with partials;
form_with model:; render collections withrender @products. Add Turbo Frames/Streams only where the UX needs partial updates. - Background work / mail / files as needed (job, mailer, attachment) — always through Active Job / Action Mailer / Active Storage, never raw threads or manual file paths.
- Tests. Model spec + request spec at minimum; a system spec for any
nontrivial user flow. FactoryBot factories for data (
testing.md). - Verify.
bundle exec rspec(or the project's suite), thenbin/rubocop -a, or the whole gate:bin/ci. Fix everything it flags before declaring done.
Scaffolding (bin/rails g scaffold ...) is legitimate for standard CRUD —
generate, then trim what isn't needed.
Conventions cheat sheet (apply everywhere)
- Strong params:
params.expect(user: [:email, :name])— notrequire/permitin new 8.x code, neverpermit!. - Turbo-compatible responses: redirect after mutation with
status: :see_other(303); re-render invalid forms withstatus: :unprocessable_entity(422). Turbo silently breaks without these. - Partials take locals, not ivars. Declare them:
<%# locals: (product:, show_price: true) %>(strict locals). - Time:
Time.current,2.days.ago,travel_toin tests. NeverTime.now/Date.todayin app code (they ignore the app time zone). - Queries: scopes on the model;
includesto kill N+1s;find_eachfor batches; no SQL string interpolation — ever (where("name = ?", n)or hash conditions). - Callbacks: fine for the object's own lifecycle (normalize, cache a column, enqueue its own follow-up job); avoid reaching into other models from callbacks — do that in the controller/job that orchestrates.
- I18n-ready copy in views (
t(".title")) when the app already uses locales; hardcode English only in single-locale apps. - Credentials, not ENV, for app secrets:
Rails.application.credentials.dig(:stripe, :secret_key); edit viabin/rails credentials:edit. - Run
bin/rubocopmentally: 2-space indent,frozen_string_literalnot required (omakase), double quotes, noand/orfor control flow.
New in 8.1 — reach for these when relevant
- Active Job Continuations — long jobs resume from the last completed
stepafter a deploy/restart instead of starting over. (jobs-and-realtime.md) - Structured Event Reporting —
Rails.event.notify("user.signup", user_id: 123)withtagged/set_contextand pluggable subscribers, for machine-readable telemetry alongside the human log. (observability.md) - Local CI —
config/ci.rbDSL run bybin/ci: setup, RuboCop, bundler-audit,bin/importmap audit, Brakeman, tests, optionalgh signoff. (testing.md) - Markdown rendering —
render markdown: @page/format.md/.md.erbtemplates; useful for docs pages and AI-facing endpoints. (views-hotwire.md) bin/rails credentials:fetch some.key— shell-friendly credential reads, e.g. in.kamal/secrets. (deployment-kamal.md)- Deprecated associations —
has_many :posts, deprecated: truereports every usage (:warn/:raise/:notify) to help retire schema. (models.md) - Registry-free Kamal deploys — Kamal 2.8 uses a local registry by
default for simple deploys; no Docker Hub/GHCR needed to start.
(
deployment-kamal.md) - Alphabetized
schema.rbcolumns — expect reordered-but-equivalent schema diffs after the first 8.1 migration; don't "fix" them. - Verbose redirect logs in development
(
config.action_dispatch.verbose_redirect_logs = truein new apps).
Deprecations to avoid in new code: order-dependent finders (.first/.last)
on relations with no inferable order — add an explicit .order;
signed_id_verifier_secret (use Rails.application.message_verifiers);
String#mb_chars; update_all with WITH/DISTINCT.
Reference files — read before working in an area
Read the relevant file(s) before writing code in that area; they contain the exact APIs, generated-file layouts, and the traps.
| Read | When the task involves |
|---|---|
references/project-setup.md | rails new, app structure, generators, config/environments, credentials, dev workflow (bin/setup, bin/dev), upgrading |
references/models.md | Migrations, Active Record models, validations, associations, callbacks, scopes/queries, enums, normalizes, tokens, encryption, multi-DB |
references/controllers-routing.md | Routes, URL design (human vanity paths for user-facing pages vs REST for records + JSON API; the reconciliation), controllers, params.expect, filters, rate limiting, sessions/cookies/flash, redirects & status codes, API-only apps |
references/views-hotwire.md | ERB, layouts, partials, helpers, form_with, Turbo Drive/Frames/Streams, morphing, Stimulus, importmap/Propshaft, markdown rendering |
references/jobs-and-realtime.md | Active Job, Solid Queue, recurring jobs, 8.1 continuations, concurrency limits, Action Cable / Solid Cable |
references/mail-storage-richtext.md | Action Mailer, Action Mailbox, Active Storage (uploads/variants/direct upload), Action Text |
references/auth-security.md | bin/rails g authentication, sessions, password reset, authorization patterns, CSRF/XSS/SQLi, CSP, the security checklist |
references/sso.md | Enterprise SSO: multi-tenant OIDC (default) + SAML hatch, identities keyed [provider, issuer, uid], JIT roles, enabled-vs-enforced, tenant dashboard, cert rotation, SLO, audit, RSpec proving set |
references/testing.md | RSpec (pure — no matcher add-ons), FactoryBot/Faker, request/system specs, Capybara, WebMock/VCR, SimpleCov, bin/ci, --skip-test scaffolding |
references/performance-caching.md | Solid Cache, fragment/russian-doll caching, HTTP caching/ETags, N+1s, load_async, counter caches, YJIT/jemalloc/Puma/Thruster, profiling |
references/observability.md | Active Support Instrumentation (hook catalog, subscribers, custom events), 8.1 Rails.event, Rails.error, log tagging, APM/OpenTelemetry wiring |
references/advanced-active-record.md | Composite primary keys, multiple databases (replicas, role switching, sharding), Active Record encryption + key rotation |
references/ecosystem-gems.md | simple_form, tailwindcss-rails, OmniAuth, Pundit/CanCanCan, Pagy, Ransack/pg_search, mission_control-jobs, friendly_id, paper_trail, bullet, ViewComponent, strong_migrations, and when to prefer the defaults |
references/api-documentation.md | OpenAPI/Swagger for JSON APIs — rswag (test-driven docs), rspec-openapi, apipie, Swagger UI/Redoc, CI drift gates |
references/ai-llm.md | LLM features via ruby_llm — chat, acts_as_chat persistence, streaming with Hotwire, tools, structured output, embeddings + pgvector, testing AI |
references/extending-rails.md | Application templates (rails new -m), custom generators, overriding built-in generator templates, engines/plugins, Rack middleware |
references/deployment-kamal.md | Kamal 2 (config/deploy.yml, secrets, accessories, rollback), Dockerfile, Thruster, SQLite-in-production, production checklist |
Companion skill: hotwire goes deeper than views-hotwire.md on Turbo,
Stimulus, and adds Hotwire Native (iOS/Android apps, bridge components,
path configuration). Use both together for frontend-heavy or mobile work.
Multiple files often apply (a "notifications" feature touches models, jobs,
views-hotwire, and testing). Skim all that apply; don't guess APIs from
memory when the file is one view away.
Deviations and existing codebases
When dropped into an existing app, first read: Gemfile, config/routes.rb,
config/application.rb + the current environment file, db/schema.rb, and
one representative model/controller/view. Match the app's established
patterns (RSpec? service objects? ViewComponent? Tailwind?) even where this
skill prefers otherwise — consistency beats purity. Flag, don't silently
"fix", conventions you'd change.
Definition of done
A change is done when: migrations run cleanly both ways where practical,
bundle exec rspec (or the project's suite) passes, bin/rubocop is clean,
Brakeman raises no new warnings, and — for full-gate confidence — bin/ci
passes. For UI work, state which Turbo behavior was used and why. Never hand
back code you haven't at least boot-checked (bin/rails runner, a test, or
bin/rails zeitwerk:check for autoloading-sensitive changes) when a runtime
is available.