Community Ruby on Rails Design System Best Practices
Comprehensive design system guide for Ruby on Rails applications, maintained by Community. Contains 51 rules across 9 categories, prioritized by impact to guide automated refactoring and code generation. Covers the full Rails frontend stack: Turbo (Drive, Frames, Streams), Stimulus, ERB partials, design tokens, form builders, and view helpers. Complements rails-dev (controllers, models, queries) and tailwind (CSS patterns) by covering the systematic UI component architecture layer.
When to Apply
Reference these guidelines when:
- Deciding whether to extract a partial, component, or helper
- Defining design tokens with Tailwind CSS
@theme
- Creating or refactoring ERB partials with explicit locals
- Decomposing pages into Turbo Frames for targeted updates
- Using Turbo Streams for multi-element CRUD updates
- Coordinating Turbo navigation with Stimulus controllers
- Building ViewComponent or Phlex components for complex UI
- Implementing a custom FormBuilder for consistent forms
- Writing view helpers for badges, icons, and conditional classes
- Adding Stimulus controllers for interactive behaviors
- Managing JavaScript dependencies with Import Maps
- Auditing the codebase for UI duplication and naming drift
Rule Categories by Priority
| Priority |
Category |
Impact |
Prefix |
| 1 |
Design Decisions |
CRITICAL |
decide- |
| 2 |
Design Tokens |
CRITICAL |
token- |
| 3 |
Turbo Integration |
HIGH |
turbo- |
| 4 |
Partial Patterns |
HIGH |
partial- |
| 5 |
Component Architecture |
HIGH |
comp- |
| 6 |
Form System |
MEDIUM-HIGH |
form- |
| 7 |
Helper Patterns |
MEDIUM |
helper- |
| 8 |
Stimulus Behaviors |
MEDIUM |
stim- |
| 9 |
Consistency & Organization |
LOW-MEDIUM |
org- |
Quick Reference
1. Design Decisions (CRITICAL)
decide-three-uses-rule - Extract only after a pattern appears in 3+ places
decide-partial-vs-component - Choose partials for simple reuse, components for complex logic
decide-helper-vs-partial - Use helpers for tiny HTML fragments, partials for layout blocks
decide-prove-then-extract - Prove patterns in production before abstracting
decide-avoid-wrapper-components - Avoid thin wrappers that add indirection without value
decide-design-system-scope - Scope the design system to what the app actually needs
2. Design Tokens (CRITICAL)
token-tailwind-theme - Define tokens with Tailwind CSS @theme directive
token-semantic-color-names - Name colors by purpose, not appearance
token-spacing-scale - Use a constrained spacing scale for consistent layout
token-typography-scale - Define a typography scale for headings, body, and UI text
token-component-tokens - Create component-level tokens for repeated patterns
token-share-tokens-with-ruby - Share token values between CSS and Ruby when needed
3. Turbo Integration (HIGH)
turbo-drive-defaults - Let Turbo Drive handle navigation by default
turbo-frame-decompose - Decompose pages into Turbo Frames for targeted updates
turbo-frame-naming - Name Turbo Frames with dom_id conventions
turbo-frame-vs-stream - Choose Turbo Frames vs Turbo Streams by scope of change
turbo-stream-crud - Use Turbo Streams for multi-element page updates
turbo-stimulus-coordination - Coordinate Turbo and Stimulus without conflicts
4. Partial Patterns (HIGH)
partial-explicit-locals - Always pass locals explicitly to partials
partial-presenter-objects - Use presenter objects to encapsulate view logic
partial-naming-conventions - Name partials by what they render, prefixed with underscore
partial-yield-blocks - Use yield blocks for flexible partial layouts
partial-collection-with-spacer - Use collection rendering with spacer templates
partial-shared-directory - Place cross-controller partials in app/views/shared
5. Component Architecture (HIGH)
comp-when-to-use - Use components when partials outgrow simple rendering
comp-explicit-args - Define explicit typed arguments for every component
comp-slots-for-markup - Use slots for caller-provided markup blocks
comp-test-rendered-output - Test components by asserting on rendered HTML
6. Form System (MEDIUM-HIGH)
form-custom-builder - Create a custom FormBuilder for consistent form rendering
form-set-default-builder - Set the custom builder as the application default
form-error-display - Display field errors inline with consistent markup
form-accessible-labels - Generate accessible labels and ARIA attributes automatically
form-group-wrapper - Wrap label + input + error in a consistent group element
form-button-consistency - Standardize submit buttons through the form builder
7. Helper Patterns (MEDIUM)
helper-tag-helpers - Use tag helpers for small generated HTML fragments
helper-conditional-classes - Use class_names for conditional CSS classes
helper-icon-helper - Create an icon helper for consistent icon rendering
helper-badge-pattern - Build a badge helper for status indicators
helper-scope-to-domain - Scope helpers to specific domains, not generic utilities
8. Stimulus Behaviors (MEDIUM)
stim-general-purpose - Write general-purpose controllers, not one-off scripts
stim-data-attribute-config - Configure behavior through data attributes, not JavaScript
stim-small-controllers - Keep controllers small and single-responsibility
stim-composable-controllers - Compose multiple controllers on one element
stim-use-outlets - Use outlets for cross-controller communication
stim-leverage-library - Use stimulus-components before writing custom controllers
9. Consistency & Organization (LOW-MEDIUM)
org-naming-conventions - Follow consistent naming across partials, components, and helpers
org-file-structure - Organize design system files in predictable locations
org-deduplication-audit - Periodically audit views for duplicated patterns
org-import-maps - Use Import Maps for zero-build JavaScript delivery
org-preview-with-lookbook - Preview components with Lookbook in development
org-document-design-decisions - Document design system decisions in ADRs
How to Use
Read individual reference files for detailed explanations and code examples:
- Section definitions - Category structure and impact levels
- Rule template - Template for adding new rules
Reference Files
| File |
Description |
| references/_sections.md |
Category definitions and ordering |
| assets/templates/_template.md |
Template for new rules |
| metadata.json |
Version and reference information |
1---2name: rails-design-system3description: Ruby on Rails design system guidelines for building consistent, maintainable UI with minimal abstraction. This skill should be used when creating or refactoring Rails views, partials, components, form builders, helpers, Stimulus controllers, Turbo Frames, Turbo Streams, or design tokens. Triggers on tasks involving ERB partials, Turbo navigation, Turbo Streams, ViewComponent, Phlex, Tailwind design tokens, custom form builders, view helpers, Stimulus behaviors, Import Maps, Lookbook previews, or design system consistency audits.4---5
6# Community Ruby on Rails Design System Best Practices
7
8Comprehensive design system guide for Ruby on Rails applications, maintained by Community. Contains 51 rules across 9 categories, prioritized by impact to guide automated refactoring and code generation. Covers the full Rails frontend stack: Turbo (Drive, Frames, Streams), Stimulus, ERB partials, design tokens, form builders, and view helpers. Complements `rails-dev` (controllers, models, queries) and `tailwind` (CSS patterns) by covering the systematic UI component architecture layer.
9
10## When to Apply
11
12Reference these guidelines when:
13- Deciding whether to extract a partial, component, or helper
14- Defining design tokens with Tailwind CSS `@theme`
15- Creating or refactoring ERB partials with explicit locals
16- Decomposing pages into Turbo Frames for targeted updates
17- Using Turbo Streams for multi-element CRUD updates
18- Coordinating Turbo navigation with Stimulus controllers
19- Building ViewComponent or Phlex components for complex UI
20- Implementing a custom FormBuilder for consistent forms
21- Writing view helpers for badges, icons, and conditional classes
22- Adding Stimulus controllers for interactive behaviors
23- Managing JavaScript dependencies with Import Maps
24- Auditing the codebase for UI duplication and naming drift
25
26## Rule Categories by Priority
27
28| Priority | Category | Impact | Prefix |
29|----------|----------|--------|--------|
30| 1 | Design Decisions | CRITICAL | `decide-` |
31| 2 | Design Tokens | CRITICAL | `token-` |
32| 3 | Turbo Integration | HIGH | `turbo-` |
33| 4 | Partial Patterns | HIGH | `partial-` |
34| 5 | Component Architecture | HIGH | `comp-` |
35| 6 | Form System | MEDIUM-HIGH | `form-` |
36| 7 | Helper Patterns | MEDIUM | `helper-` |
37| 8 | Stimulus Behaviors | MEDIUM | `stim-` |
38| 9 | Consistency & Organization | LOW-MEDIUM | `org-` |
39
40## Quick Reference
41
42### 1. Design Decisions (CRITICAL)
43
44- [`decide-three-uses-rule`](references/decide-three-uses-rule.md) - Extract only after a pattern appears in 3+ places
45- [`decide-partial-vs-component`](references/decide-partial-vs-component.md) - Choose partials for simple reuse, components for complex logic
46- [`decide-helper-vs-partial`](references/decide-helper-vs-partial.md) - Use helpers for tiny HTML fragments, partials for layout blocks
47- [`decide-prove-then-extract`](references/decide-prove-then-extract.md) - Prove patterns in production before abstracting
48- [`decide-avoid-wrapper-components`](references/decide-avoid-wrapper-components.md) - Avoid thin wrappers that add indirection without value
49- [`decide-design-system-scope`](references/decide-design-system-scope.md) - Scope the design system to what the app actually needs
50
51### 2. Design Tokens (CRITICAL)
52
53- [`token-tailwind-theme`](references/token-tailwind-theme.md) - Define tokens with Tailwind CSS @theme directive
54- [`token-semantic-color-names`](references/token-semantic-color-names.md) - Name colors by purpose, not appearance
55- [`token-spacing-scale`](references/token-spacing-scale.md) - Use a constrained spacing scale for consistent layout
56- [`token-typography-scale`](references/token-typography-scale.md) - Define a typography scale for headings, body, and UI text
57- [`token-component-tokens`](references/token-component-tokens.md) - Create component-level tokens for repeated patterns
58- [`token-share-tokens-with-ruby`](references/token-share-tokens-with-ruby.md) - Share token values between CSS and Ruby when needed
59
60### 3. Turbo Integration (HIGH)
61
62- [`turbo-drive-defaults`](references/turbo-drive-defaults.md) - Let Turbo Drive handle navigation by default
63- [`turbo-frame-decompose`](references/turbo-frame-decompose.md) - Decompose pages into Turbo Frames for targeted updates
64- [`turbo-frame-naming`](references/turbo-frame-naming.md) - Name Turbo Frames with dom_id conventions
65- [`turbo-frame-vs-stream`](references/turbo-frame-vs-stream.md) - Choose Turbo Frames vs Turbo Streams by scope of change
66- [`turbo-stream-crud`](references/turbo-stream-crud.md) - Use Turbo Streams for multi-element page updates
67- [`turbo-stimulus-coordination`](references/turbo-stimulus-coordination.md) - Coordinate Turbo and Stimulus without conflicts
68
69### 4. Partial Patterns (HIGH)
70
71- [`partial-explicit-locals`](references/partial-explicit-locals.md) - Always pass locals explicitly to partials
72- [`partial-presenter-objects`](references/partial-presenter-objects.md) - Use presenter objects to encapsulate view logic
73- [`partial-naming-conventions`](references/partial-naming-conventions.md) - Name partials by what they render, prefixed with underscore
74- [`partial-yield-blocks`](references/partial-yield-blocks.md) - Use yield blocks for flexible partial layouts
75- [`partial-collection-with-spacer`](references/partial-collection-with-spacer.md) - Use collection rendering with spacer templates
76- [`partial-shared-directory`](references/partial-shared-directory.md) - Place cross-controller partials in app/views/shared
77
78### 5. Component Architecture (HIGH)
79
80- [`comp-when-to-use`](references/comp-when-to-use.md) - Use components when partials outgrow simple rendering
81- [`comp-explicit-args`](references/comp-explicit-args.md) - Define explicit typed arguments for every component
82- [`comp-slots-for-markup`](references/comp-slots-for-markup.md) - Use slots for caller-provided markup blocks
83- [`comp-test-rendered-output`](references/comp-test-rendered-output.md) - Test components by asserting on rendered HTML
84
85### 6. Form System (MEDIUM-HIGH)
86
87- [`form-custom-builder`](references/form-custom-builder.md) - Create a custom FormBuilder for consistent form rendering
88- [`form-set-default-builder`](references/form-set-default-builder.md) - Set the custom builder as the application default
89- [`form-error-display`](references/form-error-display.md) - Display field errors inline with consistent markup
90- [`form-accessible-labels`](references/form-accessible-labels.md) - Generate accessible labels and ARIA attributes automatically
91- [`form-group-wrapper`](references/form-group-wrapper.md) - Wrap label + input + error in a consistent group element
92- [`form-button-consistency`](references/form-button-consistency.md) - Standardize submit buttons through the form builder
93
94### 7. Helper Patterns (MEDIUM)
95
96- [`helper-tag-helpers`](references/helper-tag-helpers.md) - Use tag helpers for small generated HTML fragments
97- [`helper-conditional-classes`](references/helper-conditional-classes.md) - Use class_names for conditional CSS classes
98- [`helper-icon-helper`](references/helper-icon-helper.md) - Create an icon helper for consistent icon rendering
99- [`helper-badge-pattern`](references/helper-badge-pattern.md) - Build a badge helper for status indicators
100- [`helper-scope-to-domain`](references/helper-scope-to-domain.md) - Scope helpers to specific domains, not generic utilities
101
102### 8. Stimulus Behaviors (MEDIUM)
103
104- [`stim-general-purpose`](references/stim-general-purpose.md) - Write general-purpose controllers, not one-off scripts
105- [`stim-data-attribute-config`](references/stim-data-attribute-config.md) - Configure behavior through data attributes, not JavaScript
106- [`stim-small-controllers`](references/stim-small-controllers.md) - Keep controllers small and single-responsibility
107- [`stim-composable-controllers`](references/stim-composable-controllers.md) - Compose multiple controllers on one element
108- [`stim-use-outlets`](references/stim-use-outlets.md) - Use outlets for cross-controller communication
109- [`stim-leverage-library`](references/stim-leverage-library.md) - Use stimulus-components before writing custom controllers
110
111### 9. Consistency & Organization (LOW-MEDIUM)
112
113- [`org-naming-conventions`](references/org-naming-conventions.md) - Follow consistent naming across partials, components, and helpers
114- [`org-file-structure`](references/org-file-structure.md) - Organize design system files in predictable locations
115- [`org-deduplication-audit`](references/org-deduplication-audit.md) - Periodically audit views for duplicated patterns
116- [`org-import-maps`](references/org-import-maps.md) - Use Import Maps for zero-build JavaScript delivery
117- [`org-preview-with-lookbook`](references/org-preview-with-lookbook.md) - Preview components with Lookbook in development
118- [`org-document-design-decisions`](references/org-document-design-decisions.md) - Document design system decisions in ADRs
119
120## How to Use
121
122Read individual reference files for detailed explanations and code examples:
123
124- [Section definitions](references/_sections.md) - Category structure and impact levels
125- [Rule template](assets/templates/_template.md) - Template for adding new rules
126
127## Reference Files
128
129| File | Description |
130|------|-------------|
131| [references/_sections.md](references/_sections.md) | Category definitions and ordering |
132| [assets/templates/_template.md](assets/templates/_template.md) | Template for new rules |
133| [metadata.json](metadata.json) | Version and reference information |