Skip to content

Instantly share code, notes, and snippets.

@Julian194
Created February 8, 2026 10:16
Show Gist options
  • Select an option

  • Save Julian194/3703514629c58a55e772d22773744371 to your computer and use it in GitHub Desktop.

Select an option

Save Julian194/3703514629c58a55e772d22773744371 to your computer and use it in GitHub Desktop.
37signals Rails Guide — Progressive Disclosure Skill for Claude Code / pi (wraps marckohlbrugge/unofficial-37signals-coding-style-guide)

37signals Rails Guide - Pins Index

Use: grep this file to find relevant files, then fetch specific sections

FILE PINS (keyword | file | one-liner)

auth login session magic-link devise passwordless | authentication.md | Passwordless magic links ~150 LOC, no Devise controller thin concern crud | controllers.md | Thin controllers, rich models, composable concerns model concern state record | models.md | Rich domain models, concerns, state as records view partial turbo-stream morph broadcast | views.md | Turbo Streams, partials over components route crud resource namespace shallow | routing.md | Everything is CRUD, resource-based routing database uuid state-record counter-cache index | database.md | UUIDs, state as records, no soft deletes

hotwire turbo morph frame | hotwire.md | Turbo morphing, frames, common issues stimulus javascript controller reusable | stimulus.md | Small focused reusable JS controllers css cascade-layer oklch dark-mode nesting | css.md | Native CSS, cascade layers, OKLCH colors action-text rich-text sanitizer trix | action-text.md | Rich text editing, sanitizer config

job queue solid-queue background recurring | background-jobs.md | Solid Queue patterns, stagger jobs cache etag fragment lazy | caching.md | HTTP caching, fragment caching, lazy load actioncable websocket broadcast cable | actioncable.md | Multi-tenant WebSockets, Solid Cable storage upload avatar variant preview | active-storage.md | File uploads, variants, previews email mailer smtp timezone unsubscribe | email.md | Multi-tenant mailers, timezone handling

multi-tenant tenant account path-based | multi-tenancy.md | URL path-based multi-tenancy filter query url-state chip | filtering.md | Filter objects, URL-based state notification bundle preference realtime | notifications.md | Time window bundling, preferences watch subscription toggle involvement | watching.md | Subscription patterns, toggle UI webhook ssrf retry signature delivery | webhooks.md | SSRF protection, state machines workflow event undo command state-machine | workflows.md | Event-driven state, undoable commands

test minitest fixture integration system | testing.md | Minitest with fixtures, simple fast security xss csrf ssrf csp rate-limit | security-checklist.md | Security patterns and gotchas performance n+1 pagination puma batch | performance.md | DB, CSS, rendering optimizations observability logging metrics yabeda otel | observability.md | Structured logging, Yabeda metrics accessibility aria keyboard screen-reader focus | accessibility.md | ARIA, keyboard nav, focus mgmt mobile responsive touch safe-area | mobile.md | Responsive CSS, touch, safe areas

philosophy ship vanilla extract | development-philosophy.md | Ship-validate-refine, vanilla Rails avoid devise pundit service-object graphql sidekiq react | what-they-avoid.md | What they DON'T use config environment yaml kamal master-key | configuration.md | Rails config, env management ai llm command context cost tool | ai-llm.md | AI/LLM integration patterns

dhh david review abstraction | dhh.md | DHH's review style and patterns jorge manrubia architecture | jorge-manrubia.md | Jorge Manrubia's patterns jason zimdars design ux | jason-zimdars.md | Jason Zimdars' design patterns


SECTION PINS (file:section | keywords)

authentication.md

authentication.md:Magic Link Flow | magic-link email token authentication.md:Identity Model | identity user authentication.md:Session Model | session cookie authentication.md:Authentication Concern | concern current_user authentication.md:Why Not Devise? | devise avoid

controllers.md

controllers.md:Core Principle | thin rich controllers.md:Authorization | authorize check controllers.md:Controller Concerns Catalog | concern list controllers.md:Composing Concerns | compose mix

models.md

models.md:Heavy Use of Concerns | concern horizontal models.md:State as Records | state boolean record models.md:Current for Request Context | current thread models.md:Let It Crash | bang exception models.md:PORO Patterns | poro plain-ruby

hotwire.md

hotwire.md:Turbo Morphing | morph refresh hotwire.md:Turbo Frames | frame lazy hotwire.md:Common Turbo Issues | issue problem debug hotwire.md:Stimulus Best Practices | stimulus practice hotwire.md:Links Over JavaScript | link navigate

testing.md

testing.md:Minitest Over RSpec | minitest rspec testing.md:Fixtures Over Factories | fixture factory testing.md:Integration Tests | integration request testing.md:System Tests | system browser capybara

security-checklist.md

security-checklist.md:XSS Prevention | xss escape security-checklist.md:CSRF Protection | csrf token security-checklist.md:SSRF | ssrf request security-checklist.md:Content Security Policy | csp header security-checklist.md:Rate Limiting | rate limit throttle

what-they-avoid.md

what-they-avoid.md:Notable Absences | absent missing what-they-avoid.md:No Devise | devise auth what-they-avoid.md:No Pundit | pundit cancan authorize what-they-avoid.md:Service Objects | service object what-they-avoid.md:ViewComponent | viewcomponent component what-they-avoid.md:GraphQL | graphql api what-they-avoid.md:Sidekiq | sidekiq job what-they-avoid.md:React/Vue | react vue spa frontend

name rails-guide
description Query 37signals Rails patterns with progressive disclosure. Token-efficient lookups for auth, controllers, hotwire, testing, etc.
compatibility Requires content symlink to local clone of marckohlbrugge/unofficial-37signals-coding-style-guide
metadata
author version source
kaiserlich
1.2
marckohlbrugge/unofficial-37signals-coding-style-guide

37signals Rails Guide - Progressive Disclosure

This skill is a progressive disclosure layer on top of Mark Kohlbrugge's unofficial 37signals coding style guide. You need to clone that repo first (see Setup below). The PINS.md and TOC.md files in this gist index the guide content so an LLM can look up patterns efficiently without loading everything at once.

Pins: {baseDir}/PINS.md (keyword → file) TOC: {baseDir}/TOC.md (all section headings) Content: {baseDir}/content/*.md (symlink to repo clone)

Usage Pattern (Token-Efficient)

Step 0: Sync first (always run this)

bash {baseDir}/update.sh

Step 1: Find relevant file(s)

grep -i "KEYWORD" {baseDir}/PINS.md | head -5

Returns: keywords | file.md | one-liner

Step 2: Get section headings

grep -A 20 "^# FILENAME" {baseDir}/TOC.md

Returns: List of - Section headings

Step 3: Fetch specific section

sed -n '/^## TARGET_SECTION/,/^## /p' {baseDir}/content/FILE.md | head -80

Quick Examples

# "How do they handle auth?"
grep -i "auth" {baseDir}/PINS.md | head -3

# "What sections in authentication.md?"
grep -A 15 "^# authentication" {baseDir}/TOC.md

# "Show MagicLink Model"
sed -n '/^## MagicLink Model/,/^## /p' {baseDir}/content/authentication.md | head -50

# "What do they avoid?"
grep -i "avoid" {baseDir}/PINS.md

Common Queries → Files

Query File Key Sections
auth, login, session authentication.md Magic Link Flow, Session Model
controller, concern controllers.md Core Principle, Concerns Catalog
model, state models.md State as Records, Concerns
turbo, hotwire, morph hotwire.md Turbo Morphing, Turbo Frames
stimulus, javascript stimulus.md Philosophy, Reusable Controllers
test, fixture testing.md Minitest Over RSpec, Fixtures
avoid, dont, skip what-they-avoid.md Notable Absences
security, xss, csrf security-checklist.md XSS, CSRF, SSRF
job, queue, background background-jobs.md Solid Queue patterns
multi-tenant, account multi-tenancy.md Path-Based Tenancy

Cross-References

Topic Also Check
auth security-checklist.md
controllers models.md (shared concerns)
hotwire stimulus.md, views.md
testing what-they-avoid.md
jobs multi-tenancy.md
security webhooks.md

Token Budget

Step Tokens
Pins lookup ~5
TOC sections ~15
One section ~50-80
Full file 100-800 ⚠️

Always start with Step 1, escalate only if needed.

Setup on New Machine

# Clone the 37signals guide
git clone git@github.com:marckohlbrugge/unofficial-37signals-coding-style-guide.git ~/code/37signals-guide

# Create content symlink in skills directory
ln -s ~/code/37signals-guide ~/.claude/skills/rails-guide/content

accessibility

  • ARIA Patterns
  • Keyboard Navigation
  • Screen Reader Considerations
  • Focus Management
  • Testing Accessibility
  • Platform-Specific Considerations
  • Common Patterns
  • Quick Wins Checklist
  • Resources

actioncable

  • Connection Management
  • Broadcast Strategies
  • Turbo Stream Patterns
  • Multi-Tenant ActionCable Configuration
  • Monitoring and Metrics
  • Testing Patterns
  • Performance Considerations
  • Summary

action-text

  • Sanitizer Configuration in Production
    1. Custom HTML Processing at Render Time
    1. Link Retargeting for Turbo Frame Escaping
    1. Graceful Handling of Malformed Attachments
    1. Custom Attachable Partials
    1. Comprehensive Rich Text CSS Styling
    1. Testing Helpers for Rich Text
    1. Rich Text Applied to Forms (Edge Case)
  • Summary of Key Takeaways

active-storage

  • Variant Preprocessing (#767)
  • Direct Upload Expiry (#773)
  • Large File Preview Limits (#941)
  • Preview vs Variant (#770)
  • Avatar Optimization (#1689)
  • Mirror Configuration (#557)

ai-llm

  • Command Pattern with STI (#460, #464, #466)
  • Context Objects for Parsing (#460)
  • Cost Tracking in Microcents (#978)
  • Result Objects for Responses (#460, #857)
  • Tool Pattern for LLM Function Calling (#857)
  • Confirmation Pattern for Bulk Operations (#464)
  • Filter Registry Pattern (#857)
  • Order Clause Parser (#857)
  • Code Review Culture

authentication

  • Why Not Devise?
  • Magic Link Flow
  • Identity Model
  • MagicLink Model
  • Session Model
  • Authentication Concern
  • Sessions Controller
  • Magic Link Controller
  • Magic Link Mailer
  • Current Context
  • Multi-Account Support
  • Session Path Scoping
  • Development Convenience
  • Key Principles

background-jobs

  • Configuration
  • Stagger Recurring Jobs
  • Transaction Safety
  • Error Handling
  • Maintenance Jobs
  • Job Patterns
  • Continuable Jobs for Resilient Iteration (#1083)

caching

  • HTTP Caching (ETags)
  • Fragment Caching
  • Lazy-Loaded Content with Turbo Frames (#1089)
  • User-Specific Content in Cached Fragments
  • Extract Dynamic Content to Turbo Frames (#317)

CLAUDE

  • Repository Purpose
  • Structure
  • Content Guidelines

configuration

  • RAILS_MASTER_KEY Pattern (#554)
  • YAML Configuration DRYness
  • Environment-Specific Configuration
  • Test Environment Handling
  • Environment Variable Precedence
  • Development Environment Configuration
  • Kamal Deployment Configuration
  • Configuration Organization Principles

controllers

  • Core Principle: Thin Controllers, Rich Models
  • ApplicationController is Minimal
  • Authorization: Controller Checks, Model Defines
  • Controller Concerns Catalog
  • Composing Concerns: Real Controllers
  • Concern Composition Rules

css

  • Philosophy
  • Cascade Layers
  • OKLCH Color Space
  • Dark Mode via CSS Variables
  • Native CSS Nesting
  • Component Naming Convention
  • CSS Variables for Component APIs
  • Modern CSS Features Used
  • Utility Classes (Minimal)
  • Design Tokens
  • Responsive Strategy
  • File Organization
  • What's NOT Here
  • Key Principles

database

  • UUIDs as Primary Keys
  • State as Records, Not Booleans
  • Database-Backed Infrastructure
  • Account ID Everywhere
  • No Soft Deletes
  • Counter Caches
  • Minimal Foreign Keys
  • Index Strategy
  • Sharded Search
  • Key Principles

development-philosophy

  • Ship, Validate, Refine
  • Fix Root Causes, Not Symptoms
  • Vanilla Rails Over Abstractions
  • DHH's Review Patterns
  • Common Review Themes
  • When to Extract
  • Rails 7.1+ params.expect (#120)
  • StringInquirer for Action Predicates (#425)
  • Caching Constraints Inform Architecture (#119)
  • Write-Time vs Read-Time Operations (#108)
  • Jason Zimdars: Design & Product Patterns
  • Jorge Manrubia: Architecture & Rails Patterns
  • Rails Patterns

dhh

  • Core Philosophy: Earn Your Abstractions
  • Write-Time vs Read-Time Operations
  • Database Over Application Logic
  • Naming Principles
  • Rails Conventions
  • View Patterns
  • JavaScript / Stimulus Patterns
  • Testing Philosophy
  • Migrations
  • Be Explicit Over Clever
  • Caching Principles
  • API Design
  • Routing
  • Data Defaults
  • Authorization Patterns
  • Key Takeaways
  • References

email

  • Multi-Tenant URL Helpers in Mailers
    1. User Timezone Awareness in Email Delivery
    1. SVG Fallbacks for Email Avatars
    1. Environment-Based SMTP Configuration
    1. SMTP Delivery Error Handling
    1. Batch Email Delivery with ActiveJob.perform_all_later
    1. One-Click Unsubscribe Headers
    1. Email Layout Best Practices
    1. Mailer Previews for Multi-Tenant Apps
    1. Testing Email Content and Structure
  • Summary: Key Takeaways

filtering

  • Filter Object Pattern
    1. Query Composition: Lazy Evaluation with Memoization
    1. URL-Based Filter State: Stateless Filtering
    1. Filter Chips as Links (PR #138)
    1. Stimulus Controllers for Filters (PR #567)
    1. Testing Filter Logic
    1. Advanced Pattern: Filter Persistence with Digest
  • Summary: Key Takeaways

hotwire

  • Turbo Morphing
  • Turbo Frames
  • Common Turbo Issues
  • Stimulus Best Practices
  • State Persistence
  • Links Over JavaScript
  • Morphing + Turbo Streams
  • Element-Level Morph Events
  • Turbo Frames Preserve Form State
  • POST + Turbo Streams for UI State
  • Frame Morphing Configuration
  • Broadcasts with Turbo Streams
  • Auto-Submit Forms
  • Auto-Save Forms
  • Lazy Loading on Visibility
  • Dialog Controller Pattern
  • Copy to Clipboard
  • Hotkey Controller
  • Stimulus for Cached Fragment Personalization
  • Frame Reload on Document Morph
  • Navigable List Pattern
  • Turbo Permanent Elements
  • Testing Turbo Frames
  • Turbo Flash Helper
  • Drag and Drop Patterns
  • Progressive Installation

jason-zimdars

  • UX-First Decision Making
  • Prototype Quality Shipping
  • Known Limitations (acceptable for validation)
  • Blockers (must fix before merge)
  • Real Usage Trumps Speculation
  • Incremental Feature Addition
  • Visual Polish Through Iteration
  • Feature Design Principles
  • Feedback Style
  • CSS Container Query Patterns
  • Data-Driven Development
  • Key Takeaways
  • Application to Your Projects
  • Shipping Standard
  • If Prototype Quality

jorge-manrubia

  • Code Review Philosophy
  • Architecture Decisions
  • Performance Patterns
  • Testing Patterns
  • Rails Patterns
  • Decision-Making Process
  • Key Takeaways

mobile

  • Responsive Design Patterns
  • Mobile-First CSS Techniques
  • Touch-Optimized Interactions
  • Progressive Enhancement
  • Safe Area Insets & Native Integration
  • Checklist for Mobile-Ready Rails Apps
  • Additional Resources
  • Summary

models

  • Heavy Use of Concerns for Horizontal Behavior
  • Concern Structure: Self-Contained Behavior
  • State as Records, Not Booleans
  • Default Values via Lambdas
  • Current for Request Context
  • Minimal Validations
  • Let It Crash (Bang Methods)
  • Model Callbacks: Used Sparingly
  • PORO Patterns (Plain Old Ruby Objects)
  • Scope Naming Conventions
  • Concern Organization Guidelines

multi-tenancy

  • Path-Based Tenancy with Middleware (#283)
  • Current Context Pattern (#168, #279)
  • ActiveJob Tenant Preservation (#168)
  • Recurring Jobs: Iterate All Tenants (#279)
  • Session Cookie Path Scoping (#879)
  • Test Setup for Path-Based Tenancy (#879)
  • Always Scope Controller Lookups (#372)
  • Default Tenant for Dev Console (#168, #879)
  • Solid Cache Multi-Tenant Config (#168, #279)
  • Test Middleware in Isolation
  • Architecture Decision

notifications

  • Read State Management with Timestamps
    1. Notification Bundling with Time Windows
    1. User Preference Architecture with Settings Model
    1. Automatic Bundling via Callbacks
    1. Background Job Pattern for Batch Delivery
    1. Turbo Streams for Real-Time Notification UI
    1. Pagination with Infinite Scroll via Intersection Observer
    1. Client-Side Notification Grouping
    1. RESTful Controller Design for Notification Actions
    1. Email Unsubscribe with Signed Tokens
    1. Email Layout with Inline Styles
    1. Testing Notification Delivery
  • Summary: Key Architectural Decisions
  • Further Reading

observability

  • Structured JSON Logging (#285)
  • Multi-Tenant Context (#301)
  • User Context (#472)
  • Yabeda Metrics Stack (#1112)
  • Additional Yabeda Modules (#1165)
  • Log Configuration (#1602)
  • Console Auditing (#1834)
  • OpenTelemetry Collector (#1118)

performance

  • CSS Performance
  • Database Performance
  • Pagination
  • Active Storage
  • Rendering Performance
  • Puma/Ruby Tuning (#1283)
  • N+1 Prevention (#1747)
  • Optimistic UI for D&D (#1927)
  • Batch SQL Over N+1 Loops (#1129)

README

  • What This Is
  • What This Is Not
  • Important Caveats
  • Table of Contents
  • Quick Start: The 37signals Way
  • Acknowledgements
  • Further Reading
  • Disclaimer
  • License

routing

  • The CRUD Principle
  • Real Examples from Fizzy Routes
  • Noun-Based Resources
  • Namespace for Context
  • Use resolve for Custom URL Generation
  • Shallow Nesting
  • Singular Resources
  • Module Scoping
  • Path-Based Multi-Tenancy
  • Controller Mapping
  • API Design: Same Controllers, Different Format
  • Key Principles

security-checklist

  • XSS Prevention
  • CSRF Protection
  • SSRF (Server-Side Request Forgery)
  • ActionText / Rich Text
  • Multi-tenancy
  • Content Security Policy (#1964)
  • Sec-Fetch-Site as CSRF Fallback (#1721, #1751)
  • Rate Limiting (#1304)
  • Authorization Patterns (#1083)

stimulus

  • Philosophy
  • Reusable Controllers Catalog
  • Stimulus Best Practices
  • File Organization

testing

  • Minitest Over RSpec
  • Fixtures Over Factories
  • Fixture Relationships
  • ERB in Fixtures
  • Test Structure
  • Integration Tests
  • System Tests
  • Test Helpers
  • Testing Time
  • VCR for External APIs
  • Testing Jobs
  • When Tests Ship
  • Key Principles

views

  • Turbo Streams for Partial Updates
  • Morphing for Complex Updates
  • Turbo Stream Subscriptions in Views
  • Partials Over ViewComponents
  • Fragment Caching Patterns
  • View Helpers: Stimulus-Integrated Components
  • HTTP Caching in Views
  • Turbo Frame Patterns
  • Broadcast Patterns
  • Rendering Conventions

watching

  • Embedding Subscription State in Access Records
    1. Simplifying Involvement Levels
    1. Separating Resource-Level and Collection-Level Watching
    1. Toggle UI Patterns with Turbo
    1. Data Cleanup on Access Removal
    1. Cache Invalidation Strategies
    1. Testing Subscription Logic
  • Summary of Key Lessons

webhooks

  • SSRF Protection
  • Delivery Pattern: Asynchronous with State Machine
  • Retry Strategy: Delinquency Tracking
  • Signature Verification: HMAC-SHA256
  • Background Job Integration
  • Testing Webhooks
  • Payload Formatting: Multi-Format Support
  • Data Retention: Automatic Cleanup
  • Additional Insights
  • Summary

what-they-avoid

  • Notable Absences
  • Authentication: No Devise
  • Authorization: No Pundit/CanCanCan
  • Service Objects
  • Form Objects
  • Decorators/Presenters
  • ViewComponent
  • GraphQL
  • Sidekiq
  • React/Vue/Frontend Framework
  • Tailwind CSS
  • RSpec
  • FactoryBot
  • The Philosophy
  • What They DO Use

workflows

  • Event-Driven State Tracking
    1. After-Commit Callbacks for Default Data
    1. Cascading Workflow Changes
    1. Computed State from Associations
    1. Custom Turbo Stream Actions for Real-Time Updates
    1. Undoable Command Pattern
    1. Scope-Based Filtering with Polymorphic Support
    1. Contextual Defaults with Delegation
    1. Workflow Summary Generation
    1. Testing Workflow State Transitions
    1. Before-Create Initialization
    1. Contextual Validation and Compatibility Checks
  • Key Takeaways
  • PR References
#!/bin/bash
# Update 37signals style guide from upstream (quiet mode)
cd "$(dirname "$0")/content" || exit 1
git pull --ff-only -q 2>/dev/null && echo "✓ rails-guide synced" || echo "✓ rails-guide up-to-date"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment