Discover how to make your Rails apps feel lightning-fast without drowning in JavaScript!
Why Stimulus and Turbo (Hotwire) in Ruby on Rails? - Purpose & Use Cases
Imagine building a web page where every button click or form submission requires you to write complex JavaScript to update parts of the page manually.
You have to track which elements to change, fetch new data, and update the HTML yourself.
Manually writing JavaScript for every interaction is slow and error-prone.
It's easy to forget to update some parts or cause bugs that break the page.
Maintaining this code becomes a headache as the app grows.
Stimulus and Turbo (Hotwire) let you add interactivity and partial page updates with minimal JavaScript.
Turbo handles fast page updates by only replacing parts of the page, and Stimulus connects simple JavaScript controllers to HTML elements.
This means less code, fewer bugs, and faster development.
document.querySelector('#like-button').addEventListener('click', () => { fetch('/like').then(response => response.text()).then(html => { document.querySelector('#likes-count').innerHTML = html; }); });
<button data-action="click->like#increment">Like</button>
// Stimulus controller handles increment without manual fetch codeYou can build fast, interactive web apps that feel smooth and modern without writing tons of JavaScript.
On a blog, when a user clicks 'Like', Turbo updates just the like count instantly without reloading the whole page, and Stimulus manages the button behavior easily.
Manual JavaScript for UI updates is complex and fragile.
Stimulus and Turbo simplify interactivity with minimal code.
They help build fast, maintainable, and modern web apps.
Practice
Solution
Step 1: Understand Stimulus role
Stimulus is designed to add JavaScript behavior to HTML by connecting controllers to elements via data attributes.Step 2: Compare other options
Replacing entire page content is Turbo's job, not Stimulus. Database queries and styling are unrelated.Final Answer:
To add simple JavaScript behavior to HTML elements using controllers and data attributes -> Option AQuick Check:
Stimulus = JavaScript behavior via controllers [OK]
- Confusing Turbo's page update role with Stimulus
- Thinking Stimulus handles styling or database
- Assuming Stimulus reloads full pages
hello to a button element?Solution
Step 1: Recall Stimulus controller connection syntax
Stimulus controllers are connected using thedata-controllerattribute with the controller name.Step 2: Verify other attributes
data-actiondefines event handlers,data-targetdefines targets inside controllers,data-connectis invalid.Final Answer:
<button data-controller="hello">Click me</button> -> Option BQuick Check:
Controller connection uses data-controller [OK]
- Using data-action instead of data-controller to connect controller
- Confusing data-target with controller connection
- Using non-existent data-connect attribute
export default class extends Controller {
static targets = ["output"]
greet() {
this.outputTarget.textContent = "Hello, Stimulus!"
}
}and this HTML:<div data-controller="greeting"> <button data-action="click->greeting#greet">Say Hello</button> <span data-greeting-target="output"></span> </div>What happens when the button is clicked?
Solution
Step 1: Match controller and targets
The controller is named 'greeting' and defines an output target. The HTML uses data-controller="greeting" and data-greeting-target="output" correctly.Step 2: Understand the greet method and action
The button triggers greet on click, which sets the outputTarget's textContent to 'Hello, Stimulus!'.Final Answer:
The span text changes to 'Hello, Stimulus!' -> Option AQuick Check:
Correct controller and target update text [OK]
- Mismatching controller name and data-controller attribute
- Forgetting to define static targets array
- Expecting page reload instead of DOM update
<turbo-frame id="messages"> <%= render @messages %> </turbo-frame>When a new message is created, the frame does not update automatically. What is the likely cause?
Solution
Step 1: Understand Turbo Frame update mechanism
Turbo Frames update only if the server response includes aturbo-frameelement with the same id as the frame on the page.Step 2: Identify the problem
If the server response lacks a matchingturbo-framewrapper, Turbo cannot replace the frame content automatically.Final Answer:
The server response does not include a <turbo-frame> with matching id -> Option DQuick Check:
Matching turbo-frame id in response is required [OK]
- Changing frame id arbitrarily
- Assuming Turbo Frames can't render collections
- Forgetting to wrap response in turbo-frame tag
Solution
Step 1: Understand live search requirements
Live search updates results dynamically as the user types without full reload.Step 2: Combine Stimulus and Turbo correctly
Stimulus listens to input events and sends fetch requests. Turbo Frame updates only the results part of the page.Step 3: Evaluate other options
Reloading entire page on every keystroke is inefficient. Turbo Streams replace parts but need server push. Stimulus alone can't reload page efficiently.Final Answer:
Use a Stimulus controller to listen for input events, send fetch requests to the server, and update a Turbo Frame with the results -> Option CQuick Check:
Stimulus + Turbo Frame = dynamic partial updates [OK]
- Reloading full page on every input
- Using Turbo Frames without Stimulus for input events
- Misusing Turbo Streams for full page replacement
Ready to prove it?
Pass the test and this pattern moves unknown
