hotwire
Hotwire, Turbo & Stimulus for Rails
Expert patterns for JavaScript and Hotwire integration with Ruby on Rails.
Core Principles
- Use latest versions based on Gemfile
- Follow Rails conventions and best practices
- Use Context7 MCP or hotwire.dev for documentation
- Test JavaScript with RSpec system specs (Capybara + Cuprite)
- Review existing Stimulus controllers before creating new ones
Stimulus Controllers
Guidelines
- Keep controllers simple and focused
- Make controllers generic when possible, specific only when needed
- Never have controllers communicate with each other
- Integrate into ERB templates using Rails conventions
Structure
// app/javascript/controllers/toggle_controller.js
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["content"]
static values = { open: Boolean }
toggle() {
this.openValue = !this.openValue
}
openValueChanged() {
this.contentTarget.classList.toggle("hidden", !this.openValue)
}
}
ERB Integration
<div data-controller="toggle" data-toggle-open-value="false">
<button data-action="toggle#toggle">Toggle</button>
<div data-toggle-target="content" class="hidden">
Content here
</div>
</div>
Turbo Frames
Use for partial page updates without full refreshes.
<%= turbo_frame_tag "user_profile" do %>
<%= render @user %>
<% end %>
<!-- Link that updates only the frame -->
<%= link_to "Edit", edit_user_path(@user), data: { turbo_frame: "user_profile" } %>
Turbo Streams
Use for real-time updates from server.
# Controller
respond_to do |format|
format.turbo_stream
format.html { redirect_to @post }
end
<%# app/views/posts/create.turbo_stream.erb %>
<%= turbo_stream.prepend "posts", @post %>
<%= turbo_stream.update "post_count", Post.count %>
AJAX Requests
Use request.js for AJAX when needed:
import { get, post } from "@rails/request.js"
async function loadData() {
const response = await get("/api/data", { responseKind: "json" })
if (response.ok) {
const data = await response.json
// handle data
}
}
Import Maps
Include JavaScript libraries via import maps. Only add libraries when absolutely necessary.
# config/importmap.rb
pin "lodash", to: "https://ga.jspm.io/npm:lodash@4.17.21/lodash.js"
If import maps aren't used, follow whatever asset pipeline the application uses.
Testing
Test Hotwire features with RSpec system specs:
RSpec.describe "Posts", type: :system do
before { driven_by(:cuprite) }
it "updates post inline with Turbo" do
post = posts(:published)
visit post_path(post)
click_link "Edit"
fill_in "Title", with: "Updated Title"
click_button "Save"
expect(page).to have_content("Updated Title")
expect(page).to have_current_path(post_path(post)) # No redirect
end
end
More from aviflombaum/claude-code-in-avinyc
ux-ui
UX/UI design principles for clean, intuitive interfaces. Use when designing layouts, improving usability, planning information architecture, or ensuring accessibility. Triggers on "user experience", "usability", "information architecture", "accessibility", "interaction design".
12interview
Interview about a plan file to refine it through in-depth questioning. Use when you have a plan that needs validation, refinement, or deeper exploration before implementation. Triggers on "interview me about", "refine this plan", "question this spec".
9tailwind
Tailwind CSS patterns, utilities, and component styling for Rails. Use when styling with Tailwind, creating responsive layouts, or building UI components. Triggers on "tailwind", "style with", "css classes", "responsive layout".
9write
Write technical blog posts, tutorials, and documentation in Flatiron School's engaging style. Use for explaining code patterns, debugging stories, or turning complex topics into clear narratives. Triggers on "write a blog post", "tutorial about", "explain how", "technical writing".
8write-test
Writes comprehensive RSpec tests for Rails applications. Use when writing model specs, request specs, system specs, job specs, mailer specs, channel specs, or storage specs. Triggers on "write tests for", "add specs to", "test the User model", "create request specs", "write RSpec", "add test coverage".
8analyze
Analyze completed development work to identify automation and systematization opportunities. Use after finishing features, fixing bugs, or completing code reviews. Triggers on "analyze for automation", "what can we automate", "compound opportunities", "systematize".
8