Stimulus Explained: Just Enough JavaScript for Server-Rendered Pages
Introduction
Not every page needs a single-page app. If your server already renders good HTML — the Rails, Laravel, and Django way — bolting on React for a dropdown or a toggle is overkill, but writing jQuery spaghetti is no fun either. Stimulus, released in 2018 by the Rails team at 37signals, is the middle path: a modest JavaScript framework that attaches behaviour to HTML you already have, using conventions instead of a build step or a virtual DOM. It is JavaScript for the 90% of pages that are mostly server-rendered.
Controllers, targets, and values
Stimulus organises behaviour around three ideas, all declared in plain HTML:
- Controllers — small JavaScript classes that connect to an element via a
data-controllerattribute and run when that element appears on the page. - Targets — named elements inside a controller's scope, declared with
data-hello-target, so code readsthis.nameTargetinstead of querying the DOM by hand. - Values and actions — typed data passed through
data-hello-name-valueattributes, and behaviour wired withdata-action="click->hello#greet", keeping the HTML readable and the JavaScript small.
A greeting controller shows the whole model — HTML declares the wiring, JavaScript supplies the behaviour:
// hello_controller.js
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static targets = ["name", "output"];
greet() {
this.outputTarget.textContent =
`Hello, ${this.nameTarget.value}!`;
}
}<div data-controller="hello">
<input data-hello-target="name" type="text">
<button data-action="click->hello#greet">Greet</button>
<span data-hello-target="output"></span>
</div>No build step required, no state to synchronise, no virtual DOM: the HTML is the source of truth, and Stimulus just makes it interactive.
The honest trade
Stimulus's trade is scope: it deliberately does not do routing, global state, or complex client-side rendering, so a genuinely app-like interface will outgrow it. Its ecosystem is also smaller than React's or Vue's. The rule of thumb: Stimulus when your pages are mostly server-rendered and need sprinkles of interactivity; a full framework when the interface itself is the product.
Takeaway
Stimulus is just enough JavaScript for server-rendered pages: controllers, targets, and actions declared in HTML, with no build step and no virtual DOM. It trades app-framework power for simplicity — and for most pages, simplicity is exactly what you need.
Comments
Post a Comment