Stimulus patterns
Skill davidteren/hotwire-codex-skills/skills/stimulus-patterns
Unofficial Claude Code skillset inspired by The Rails and Hotwire Codex — 8 skills for building interactive Rails + Hotwire apps (Turbo, Stimulus, Hotwire Native) across web, iOS & Android, each with a runnable checker.
npx -y skills add davidteren/hotwire-codex-skills --skill stimulus-patternsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Write small, Turbo-safe, server-driven Stimulus controllers, and catch the mistakes that fail at runtime or leak. Use when adding a Stimulus controller, wiring elements that arrive via Turbo Streams/Frames, passing config from the server via the Values/Classes API, or debugging a controller that doesn't connect / a missing-target error / a listener that double-fires after Turbo navigation. Provides annotated templates and a controller linter.
SKILL.md
2.8 KB, as published. Nobody here has run it
Stimulus patterns
Keep controllers small, Turbo-safe, and driven by the server. Full patterns:
references/stimulus-guide.md (grounded in the Piazza controllers).
When to use
- Adding a Stimulus controller.
- Wiring elements that arrive later (Turbo Stream append, frame load) — use the
xTargetConnectedself-wiring callback instead of re-querying. - Passing data/CSS from the server (Values/Classes API).
- Debugging: a controller that never connects, a
this.fooTargetundefined error, or a listener/timer that double-fires after navigation.
The patterns (and their footguns)
- Small, single-purpose controllers — many tiny ones over one big one.
- Self-wiring via
xTargetConnected(target)— fires per element as each connects, including streamed-in ones (templates/self_wiring_controller.js.tmpl). - Values/Classes API — push config + CSS class names from ERB
(
this.fooValue,this.fooClasses); keep styling in the view. - State machine + delegate — controller toggles DOM state; a plain helper does SDK/transport plumbing and calls back.
- Clone a server
<template>— stamp repeated markup instead of building HTML in JS. - Clean up in
disconnect()— undoaddEventListener(window/document),setInterval, observers, or native UI you rendered, or it leaks and double-fires after Turbo navigation.data-actionlisteners are auto-managed; manual ones aren't.
Start a controller
sed 's/__NAME__/your-name/g' templates/controller.js.tmpl > your_name_controller.js
# or templates/self_wiring_controller.js.tmpl for the streamed-in case
Register it (manifest index.js via bin/rails stimulus:manifest:update, or
stimulus-loading) — an unregistered controller never connects.
Lint
scripts/lint_stimulus.sh path/to/rails-app # or a controllers/ dir
Flags: this.xTarget/xValue/xClass used but not declared in static targets/values/classes (runtime errors); connect() that registers a
listener/timer/observer with no disconnect() (leak/double-fire); a controller
file missing from the index.js manifest (never connects). Heuristic regex scan
(needs ruby); names its ceiling. Verified: clean on all 7 Piazza controllers,
flags a synthetic broken one on every check.