--- name: rails-hotwire description: Ruby on Rails Hotwire best practices for building interactive applications with Turbo Drive, Turbo Frames, Turbo Streams, Turbo 8 morphing, and Stimulus controllers. This skill should be used when writing, reviewing, or refactoring Hotwire-powered Rails code to ensure optimal patterns for navigation, partial page updates, real-time broadcasting, morphing, Stimulus controller design, error handling, and progressive enhancement. Triggers on tasks involving Turbo Frames, Turbo Streams, Turbo Drive, broadcasts, morphing, Stimulus controllers, ActionCable, turbo_stream_from, turbo_frame_tag, data-controller, data-action, or Hotwire performance. Complementary to rails-dev, rails-testing, rails-design-system, ruby-optimise, and ruby-refactor skills. --- # Community Rails Hotwire Best Practices Comprehensive guide for building interactive Rails applications with Hotwire (Turbo + Stimulus), maintained by Community. Contains 53 rules across 9 categories, prioritized by impact to guide automated refactoring and code generation. Follows the DHH "One Person Framework" philosophy: the server renders HTML, Turbo makes it feel like an SPA, Stimulus adds the sprinkle of JS where needed. ## When to Apply Reference these guidelines when: - Configuring Turbo Drive navigation, prefetching, and caching behavior - Adding Turbo Frames for partial page updates and lazy loading - Delivering Turbo Streams for surgical DOM mutations - Broadcasting real-time updates over ActionCable - Enabling Turbo 8 morphing for page refreshes - Writing Stimulus controllers for client-side behavior - Handling errors in Turbo navigation, frames, and WebSocket connections - Choosing between Drive, Frames, Streams, Morphing, and Stimulus - Testing Hotwire interactions in system and integration tests ## Rule Categories by Priority | Priority | Category | Impact | Prefix | |----------|----------|--------|--------| | 1 | Navigation & Drive | CRITICAL | `drive-` | | 2 | Turbo Frames | CRITICAL | `frame-` | | 3 | Turbo Streams | HIGH | `stream-` | | 4 | Broadcasting & Real-Time | HIGH | `bcast-` | | 5 | Morphing & Page Refresh | HIGH | `morph-` | | 6 | Performance Optimization | MEDIUM-HIGH | `perf-` | | 7 | Stimulus Patterns | MEDIUM-HIGH | `stim-` | | 8 | Architecture Decisions | MEDIUM | `arch-` | | 9 | Testing Hotwire | MEDIUM | `test-` | ## Quick Reference ### 1. Navigation & Drive (CRITICAL) - [`drive-prefetch-links`](references/drive-prefetch-links.md) - Enable link prefetching for instant navigation - [`drive-form-submissions`](references/drive-form-submissions.md) - Use Turbo Drive for form submissions - [`drive-visit-actions`](references/drive-visit-actions.md) - Control history with visit actions - [`drive-cache-control`](references/drive-cache-control.md) - Configure Turbo cache for preview pages - [`drive-selective-disable`](references/drive-selective-disable.md) - Disable Turbo Drive on incompatible pages - [`drive-progress-bar`](references/drive-progress-bar.md) - Customize the Turbo progress bar - [`drive-confirm-dialog`](references/drive-confirm-dialog.md) - Use data-turbo-confirm for destructive actions - [`drive-error-recovery`](references/drive-error-recovery.md) - Handle Turbo navigation and fetch errors gracefully ### 2. Turbo Frames (CRITICAL) - [`frame-lazy-loading`](references/frame-lazy-loading.md) - Defer frame loading until viewport entry - [`frame-scope-navigation`](references/frame-scope-navigation.md) - Scope navigation within frames - [`frame-src-navigation`](references/frame-src-navigation.md) - Use src for dynamic frame content - [`frame-break-out`](references/frame-break-out.md) - Handle frame breakout for redirects - [`frame-promote-visits`](references/frame-promote-visits.md) - Promote frame navigation to page visits - [`frame-dom-id`](references/frame-dom-id.md) - Use dom_id for frame identification - [`frame-empty-state`](references/frame-empty-state.md) - Provide meaningful frame loading states ### 3. Turbo Streams (HIGH) - [`stream-progressive-enhance`](references/stream-progressive-enhance.md) - Always provide HTML fallback for streams - [`stream-action-selection`](references/stream-action-selection.md) - Choose the right stream action for DOM mutations - [`stream-multi-target`](references/stream-multi-target.md) - Use targets for multi-element updates - [`stream-http-delivery`](references/stream-http-delivery.md) - Deliver streams via HTTP for form responses - [`stream-websocket-source`](references/stream-websocket-source.md) - Connect WebSocket sources in the body - [`stream-custom-actions`](references/stream-custom-actions.md) - Register custom stream actions for complex DOM updates ### 4. Broadcasting & Real-Time (HIGH) - [`bcast-model-broadcasts`](references/bcast-model-broadcasts.md) - Use broadcasts_refreshes for simple model updates - [`bcast-debounce-n1`](references/bcast-debounce-n1.md) - Debounce broadcasts to prevent N+1 broadcast storms - [`bcast-scope-streams`](references/bcast-scope-streams.md) - Scope broadcast streams to accounts or users - [`bcast-refresh-over-replace`](references/bcast-refresh-over-replace.md) - Prefer broadcast refresh over granular stream updates - [`bcast-avoid-view-logic-in-models`](references/bcast-avoid-view-logic-in-models.md) - Keep broadcasting logic out of models - [`bcast-signed-stream-names`](references/bcast-signed-stream-names.md) - Use signed stream names for security - [`bcast-reconnect-handling`](references/bcast-reconnect-handling.md) - Handle WebSocket disconnection and reconnection ### 5. Morphing & Page Refresh (HIGH) - [`morph-enable-page-refresh`](references/morph-enable-page-refresh.md) - Enable morphing for page refreshes - [`morph-permanent-elements`](references/morph-permanent-elements.md) - Mark stateful elements as permanent - [`morph-scroll-preservation`](references/morph-scroll-preservation.md) - Preserve scroll position during morphing - [`morph-stimulus-reconnect`](references/morph-stimulus-reconnect.md) - Handle Stimulus controller reconnection after morph - [`morph-frame-refresh`](references/morph-frame-refresh.md) - Use refresh='morph' on frames for additive content - [`morph-vs-streams`](references/morph-vs-streams.md) - Choose morphing over complex stream orchestration ### 6. Performance Optimization (MEDIUM-HIGH) - [`perf-optimistic-ui`](references/perf-optimistic-ui.md) - Implement optimistic UI updates before server confirmation - [`perf-batch-streams`](references/perf-batch-streams.md) - Batch multiple stream updates into single responses - [`perf-frame-caching`](references/perf-frame-caching.md) - Cache Turbo Frame responses with fragment caching - [`perf-prefetch-strategic`](references/perf-prefetch-strategic.md) - Disable prefetch on expensive endpoints - [`perf-memory-leak-prevention`](references/perf-memory-leak-prevention.md) - Clean up subscriptions and event listeners ### 7. Stimulus Patterns (MEDIUM-HIGH) - [`stim-outlets-communication`](references/stim-outlets-communication.md) - Use outlets for cross-controller communication - [`stim-values-reactive-state`](references/stim-values-reactive-state.md) - Use Values API for reactive controller state - [`stim-action-descriptors`](references/stim-action-descriptors.md) - Use declarative action descriptors over addEventListener - [`stim-small-reusable-controllers`](references/stim-small-reusable-controllers.md) - Keep Stimulus controllers small and reusable ### 8. Architecture Decisions (MEDIUM) - [`arch-progressive-enhancement`](references/arch-progressive-enhancement.md) - Follow the progressive enhancement hierarchy - [`arch-frame-vs-stream-decision`](references/arch-frame-vs-stream-decision.md) - Use frames for scoped navigation, streams for multi-target updates - [`arch-importmap-management`](references/arch-importmap-management.md) - Pin JavaScript dependencies with import maps - [`arch-avoid-client-state`](references/arch-avoid-client-state.md) - Keep state on the server, not the client - [`arch-stimulus-boundaries`](references/arch-stimulus-boundaries.md) - Use Stimulus only for client-side behavior ### 9. Testing Hotwire (MEDIUM) - [`test-system-test-async`](references/test-system-test-async.md) - Wait for Turbo updates in system tests - [`test-stream-assertions`](references/test-stream-assertions.md) - Use Turbo Stream test helpers in integration tests - [`test-broadcast-assertions`](references/test-broadcast-assertions.md) - Assert broadcasts with Turbo test helpers - [`test-frame-navigation`](references/test-frame-navigation.md) - Test frame navigation with scoped assertions - [`test-websocket-timing`](references/test-websocket-timing.md) - Handle WebSocket connection timing in system tests ## 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 |