37signals-rails — Claude Code skill: Rails rules from DHH
A rule set for Ruby on Rails the 37signals way: vanilla Rails, CRUD controllers, rich domain models, Hotwire. Useful when you write or refactor code and want to stay in that school.
npx skills add pproenca/dot-skills --skill 37signals-rails -a claude-codeWhat 37signals-rails does
The skill packs 56 rules across 8 categories, ordered by architectural impact. Sources are the Fizzy codebase, STYLE.md, AGENTS.md, the Rails Doctrine, DHH's "On Writing Software Well" series, and an unofficial style guide built from 265 Fizzy pull requests. Categories carry prefixes: arch- and ctrl- are critical, model-, state- and db- rank high, view-, style- and test- sit in the middle.
Each rule comes with reasoning. Rich domain models instead of service objects. Controllers limited to CRUD. params.expect() for parameter validation, normalizes and store_accessor, delegated_type, counter caches. Solid Queue, Solid Cache and Solid Cable for jobs, caching and pub/sub. Path-based multi-tenancy through Current.account, UUID primary keys, Turbo Frames and Turbo Streams, Stimulus, Minitest. There is also a section on patterns and gems 37signals deliberately avoids.
Rules link out to individual documents under references/. Install runs through npx skills, and the skill covers Claude, Codex, Cursor, GitHub Copilot, Gemini CLI and OpenCode. GitHub Copilot uses gh skill install instead. One thing to know before you start: the skill recommends custom passwordless auth over Devise, so on a Devise project expect the agent to argue with your existing setup.
What it helps with
- pick between a gem and vanilla Rails while designing a feature
- rewrite a controller with custom actions into plain CRUD
- move logic out of service objects into domain models
- set up background jobs, caching and pub/sub without extra services
- check code against 37signals conventions before review
Example prompts for the agent
- Rewrite this controller the 37signals way: CRUD actions only, push the logic into the model.
- Review this schema against the skill's rules — where should I use UUIDs and constraints instead of validations?
- Refactor this view for Hotwire: Turbo Frames instead of a full page reload.
How to install 37signals-rails
1Skills CLI (Vercel)
npx skills add pproenca/dot-skills --skill 37signals-rails -a claude-code2Manually: put the files in place
~/.claude/skills/37signals-rails/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/37signals-rails/
1Skills CLI (Vercel)
npx skills add pproenca/dot-skills --skill 37signals-rails -a codex2Manually: put the files in place
.agents/skills/37signals-rails/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add pproenca/dot-skills --skill 37signals-rails -a cursor2Manually: put the files in place
.cursor/skills/37signals-rails/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install pproenca/dot-skills 37signals-rails2Manually: put the files in place
.github/skills/37signals-rails/SKILL.md1Skills CLI (Vercel)
npx skills add pproenca/dot-skills --skill 37signals-rails -a gemini-cli2Platform CLI
gemini skills install https://github.com/pproenca/dot-skills --path skills/.experimental/37signals-railsManually: put the files in place
.devin/skills/37signals-rails/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add pproenca/dot-skills --skill 37signals-rails -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about 37signals-rails
How do I install 37signals-rails in Claude?
Run npx skills add pproenca/dot-skills --skill 37signals-rails -a claude-code. The skill lands at ~/.claude/skills/37signals-rails/SKILL.md.
What does the 37signals-rails skill do?
It hands your agent 56 Rails rules in the 37signals style: vanilla Rails, CRUD controllers, rich models, Hotwire, Solid Queue and Solid Cache, multi-tenancy, Minitest. The agent applies them while writing, reviewing and refactoring code.
How is it different from a regular Rails style guide?
It comes out of Basecamp, HEY and Fizzy practice rather than general advice. Several rules are deliberate rejections of common patterns and gems, service objects and Devise among them.
Source text
SKILL.md · MIT
--- name: 37signals-rails description: 37signals Rails coding principles and conventions from DHH, Jorge Manrubia, and the Fizzy/Basecamp/HEY codebase. This skill should be used when writing, reviewing, or refactoring Ruby on Rails code following the 37signals philosophy — vanilla Rails, CRUD controllers, rich domain models, concerns, no service objects, Hotwire, Turbo, Stimulus, Solid Queue, Solid Cache, Solid Cable, multi-tenancy, Minitest, custom auth, or DHH conventions. --- # 37signals Rails Best Practices Comprehensive coding principles and conventions for Ruby on Rails applications, as practiced at 37signals (Basecamp, HEY, Fizzy). Contains 56 rules across 8 categories, prioritized by architectural impact. Derived from official 37signals sources: the Fizzy codebase, STYLE.md, AGENTS.md, the Rails Doctrine, DHH's "On Writing Software Well" series, and the unofficial 37signals style guide (265 Fizzy PRs). ## When to Apply Reference these guidelines when: - Writing new Rails controllers, models, or views - Deciding between gems and vanilla Rails - Modeling state and database schema - Setting up background jobs, caching, or real-time features - Reviewing code for 37signals-style conventions - Refactoring toward rich domain models - Choosing authentication or authorization approach - Adding Stimulus controllers or Turbo patterns ## Rule Categories by Priority | Priority | Category | Impact | Prefix | |----------|----------|--------|--------| | 1 | Architecture Fundamentals | CRITICAL | `arch-` | | 2 | Controllers & REST | CRITICAL | `ctrl-` | | 3 | Domain Modeling | HIGH | `model-` | | 4 | State Management | HIGH | `state-` | | 5 | Database & Infrastructure | HIGH | `db-` | | 6 | Views & Frontend | MEDIUM | `view-` | | 7 | Code Style | MEDIUM | `style-` | | 8 | Testing | MEDIUM | `test-` | ## Quick Reference ### 1. Architecture Fundamentals (CRITICAL) - [`arch-rich-models`](references/arch-rich-models.md) - Rich Domain Models Over Service Objects - [`arch-vanilla-rails`](references/arch-vanilla-rails.md) - Vanilla Rails is Plenty - [`arch-avoid-patterns`](references/arch-avoid-patterns.md) - Deliberately Avoided Patterns and Gems - [`arch-earn-abstractions`](references/arch-earn-abstractions.md) - Earn Abstractions Through Rule of Three - [`arch-build-before-gems`](references/arch-build-before-gems.md) - Build It Yourself Before Reaching for Gems - [`arch-ship-to-learn`](references/arch-ship-to-learn.md) - Start Simple — Add Complexity Only After Validation - [`arch-domain-facades`](references/arch-domain-facades.md) - Domain Models as Facades Over Internal Complexity - [`arch-single-business-layer`](references/arch-single-business-layer.md) - Single Layer for Business Logic - [`arch-custom-auth`](references/arch-custom-auth.md) - Custom Passwordless Auth Over Devise ### 2. Controllers & REST (CRITICAL) - [`ctrl-crud-only`](references/ctrl-crud-only.md) - CRUD Controllers Over Custom Actions - [`ctrl-model-as-resources`](references/ctrl-model-as-resources.md) - Model Non-CRUD Operations as Separate Resources - [`ctrl-thin-controllers`](references/ctrl-thin-controllers.md) - Thin Controllers with Rich Domain Models - [`ctrl-params-expect`](references/ctrl-params-expect.md) - Use params.expect() for Parameter Validation - [`ctrl-controller-concerns`](references/ctrl-controller-concerns.md) - Controller Concerns for Cross-Cutting Behavior - [`ctrl-nested-resources`](references/ctrl-nested-resources.md) - Nested Resources with scope module ### 3. Domain Modeling (HIGH) - [`model-concerns`](references/model-concerns.md) - Concerns for Horizontal Code Sharing - [`model-normalizes`](references/model-normalizes.md) - Use normalizes Macro for Data Cleaning - [`model-store-accessor`](references/model-store-accessor.md) - Use store_accessor for JSON Column Access - [`model-delegated-type`](references/model-delegated-type.md) - Use delegated_type for Polymorphism - [`model-counter-caches`](references/model-counter-caches.md) - Counter Caches to Prevent N+1 Count Queries - [`model-touch-chains`](references/model-touch-chains.md) - Touch Chains for Cache Invalidation - [`model-callbacks-auxiliary`](references/model-callbacks-auxiliary.md) - Callbacks for Auxiliary Complexity - [`model-event-tracking`](references/model-event-tracking.md) - Polymorphic Event Model for Activity Tracking - [`model-poro-namespacing`](references/model-poro-namespacing.md) - Namespace POROs Under Parent Models ### 4. State Management (HIGH) - [`state-records-over-booleans`](references/state-records-over-booleans.md) - Records as State Over Boolean Columns - [`state-timestamps`](references/state-timestamps.md) - Timestamps for State Transitions - [`state-enums`](references/state-enums.md) - Enums for Categorical States - [`state-db-constraints`](references/state-db-constraints.md) - Database Constraints Over ActiveRecord Validations - [`state-write-time`](references/state-write-time.md) - Compute at Write Time Not Read Time ### 5. Database & Infrastructure (HIGH) - [`db-backed-everything`](references/db-backed-everything.md) - Database-Backed Everything - [`db-solid-queue`](references/db-solid-queue.md) - Solid Queue for Background Jobs - [`db-solid-cable`](references/db-solid-cable.md) - Solid Cable for Real-Time Pub/Sub - [`db-solid-cache`](references/db-solid-cache.md) - Solid Cache for Application Caching - [`db-multi-tenancy`](references/db-multi-tenancy.md) - Path-Based Multi-Tenancy with Current.account - [`db-uuid-primary-keys`](references/db-uuid-primary-keys.md) - UUIDs as Primary Keys - [`db-no-foreign-keys`](references/db-no-foreign-keys.md) - No Foreign Key Constraints ### 6. Views & Frontend (MEDIUM) - [`view-turbo-frames`](references/view-turbo-frames.md) - Turbo Frames for Scoped Page Fragments - [`view-turbo-streams`](references/view-turbo-streams.md) - Turbo Streams for Real-Time Updates - [`view-stimulus-targets`](references/view-stimulus-targets.md) - Stimulus Targets Over CSS Selectors - [`view-stimulus-design`](references/view-stimulus-design.md) - Stimulus Controller Design Principles - [`view-helpers-not-partials`](references/view-helpers-not-partials.md) - Extract Logic to Helpers Not Partials - [`view-progressive-enhancement`](references/view-progressive-enhancement.md) - Progressive Enhancement as Primary Pattern - [`view-fragment-caching`](references/view-fragment-caching.md) - Fragment Caching for View Performance - [`view-http-caching`](references/view-http-caching.md) - HTTP Caching with fresh_when and ETags ### 7. Code Style (MEDIUM) - [`style-conditionals`](references/style-conditionals.md) - Expanded Conditionals Over Guard Clauses - [`style-method-ordering`](references/style-method-ordering.md) - Methods Ordered by Call Sequence - [`style-positive-names`](references/style-positive-names.md) - Use Positive Names for Methods and Scopes - [`style-naming-return-values`](references/style-naming-return-values.md) - Method Names Reflect Return Values - [`style-visibility-modifiers`](references/style-visibility-modifiers.md) - Visibility Modifier Formatting - [`style-bang-methods`](references/style-bang-methods.md) - Bang Methods Only When Non-Bang Exists - [`style-async-naming`](references/style-async-naming.md) - Use _later and _now Suffixes for Async Operations ### 8. Testing (MEDIUM) - [`test-minitest`](references/test-minitest.md) - Minitest Over RSpec - [`test-fixtures`](references/test-fixtures.md) - Database Fixtures Over FactoryBot - [`test-no-damage`](references/test-no-damage.md) - No Test-Induced Design Damage - [`test-no-system-tests`](references/test-no-system-tests.md) - Integration Tests Over System Tests - [`test-behavior`](references/test-behavior.md) - Test Behavior Not Implementation ## How to Use Read individual reference files for detailed explanations and code examples: - [Section definitions](references/_sections.md) - Category structure and impact levels - [Rule template](assets/templates/_template.md) - Template for adding new rules ## Reference Files | File | Description | |------|-------------| | [references/_sections.md](references/_sections.md) | Category definitions and ordering | | [assets/templates/_template.md](assets/templates/_template.md) | Template for new rules | | [metadata.json](metadata.json) | Version and reference information |
© pproenca · MIT · pproenca/dot-skills