Hotwire Patterns
Claude Code skill with internals-informed Hotwire mental models — Turbo Drive/Frames/Streams, Morphing, Turbo Cache, ActionCable broadcasting, Stimulus design, and Hotwire Native.
A Claude Code skill that gives Claude internals-informed mental models for building and debugging Hotwire applications. Core philosophy: enhance the browser, don’t reinvent it — start by imagining a JS-free, plain-HTML version of every feature, then compose the pages into an integrated UI with Turbo. HTML is the source of truth for state, everywhere.
It complements Better Stimulus (the authority for writing controllers) and Rails Hotwire Driver (which exercises a running Hotwire app from the terminal). This skill is the knowledge layer — how Turbo and Stimulus actually work under the hood.
What Is This?
A Claude Code skill that helps Claude reason about:
- Turbo Drive, Frames, and Streams — how each observer scopes an update, and the classic frame-id mismatch that produces “Content missing”
- Morphing — the idiomorph algorithm, exactly when a morph runs, and how to exclude elements
- Turbo Cache — snapshot mechanics, preview flashing,
turbo-permanent, and cache-control - Broadcasting — ActionCable stream sources, the ~0.5s debounce, and request-id dedup
- Stimulus design — callbacks over
connect, composition via events vs outlets - Hotwire Native — Path Configuration, Bridge Components, and the native-adapter mental model
- Testing & debugging — system-test flakiness, collaborative tests, legacy migration, and internals-informed debugging
It is delivered as a skill (a knowledge module plus focused reference files), not an autonomous agent. Claude reads SKILL.md for the decision frameworks and pulls in a reference only when a specific branch needs it.
The Escalation Ladder
The skill’s central idea: Hotwire is a cost/benefit dial, not a single approach. Choose the cheapest tool that works, and escalate only when the previous rung stops being a good tradeoff:
- Turbo Drive + Morphing refreshes — re-render everything server-side; fastest to build.
- Turbo Frames — decompose the page; localize updates without touching the rest.
- Turbo Stream actions — surgical DOM updates; more precise, more maintenance cost.
- Stimulus — small client-side behavior where a server round-trip makes no sense.
- Island of a reactive framework or API calls — only for genuinely high-interactivity widgets (maps, editors).
Different parts of one app can sit on different rungs; it all composes.
Quick Start
1. Add the Marketplace
/plugin marketplace add maquina-app/rails-claude-code
2. Install the Plugin
/plugin install hotwire-patterns@maquina
3. Ask About Hotwire
The skill triggers on Hotwire design decisions and symptoms:
> Why does morphing wipe my form?
> My Turbo Stream broadcast isn't arriving
> This system test is flaky
> How do I add Turbo to a legacy app?
> Wrap my app with Hotwire Native
What It Covers
The main SKILL.md holds the decision frameworks and per-topic essentials; each deep dive lives in a reference file Claude loads on demand.
| Topic | Reference | Highlights |
|---|---|---|
| Turbo internals | (in SKILL.md) | Drive/Frames/Streams observers, _top escaping, lazy frames, the frame-id mismatch |
| Morphing | morphing.md |
idiomorph algorithm, when morph actually runs, scoped exclusion via turbo:before-morph-element |
| Turbo Cache | (in SKILL.md) | snapshot cloneNode, preview flashing, data-turbo-temporary, cache-control meta |
| Broadcasting | (in SKILL.md) | signed stream names, the background-job debounce, originating-client dedup |
| Stimulus design | stimulus.md |
callbacks over connect, events vs outlets, the dynamic-forms server-render pattern |
| Hotwire Native | hotwire-native.md |
native adapter, Path Configuration, Bridge Components, publishing |
| Testing | testing-and-legacy.md |
flakiness (assert stable state), multi-session broadcast tests, gradual Turbo adoption |
| Debugging | debugging.md |
unminify Turbo, DOM break-on breakpoints, source landmarks, ActionCable filtering |
Custom Stream Actions
A recurring theme: the correct UI update is only known server-side after processing. Custom Turbo Stream actions are the sanctioned way to run backend-driven browser behavior with a constrained, maintainable vocabulary — and they keep you CSP-compatible (no unsafe-inline):
Turbo.StreamActions.log = function () {
console.log(this.getAttribute("message"))
}
Pair with a Ruby helper module included into Turbo::Streams::TagBuilder. Prefer small, app-specific actions over dropping in large libraries.
Package Contents
hotwire-patterns/
└── skills/hotwire-patterns/
├── SKILL.md # Overview + decision frameworks + per-topic essentials
└── references/
├── morphing.md # idiomorph algorithm and gotchas
├── stimulus.md # reusable, composable controller design
├── hotwire-native.md # iOS/Android wrapping
├── testing-and-legacy.md # system tests + gradual Turbo adoption
└── debugging.md # internals-informed debugging
Team Installation
Add to your project’s .claude/settings.json:
{
"extraKnownMarketplaces": {
"maquina": {
"source": {
"source": "github",
"repo": "maquina-app/rails-claude-code"
}
}
},
"enabledPlugins": [
"hotwire-patterns@maquina"
]
}