A Better Way to Work with JavaScript Using Stimulus
stimulusjavascript
Stimulus is a lightweight JavaScript framework designed to enhance server-rendered HTML. Rather than managing state and rendering views client-side, Stimulus connects JavaScript controllers to elements that already exist on the page.
Core concepts
Stimulus revolves around three things: controllers, targets, and actions.
| Concept | HTML attribute | Purpose |
|---|---|---|
| Controller | data-controller |
Connects an element to a JS controller class |
| Target | data-[controller]-target |
References an element inside a controller |
| Action | data-action |
Wires DOM events to controller methods |
A simple example
Here’s a controller that toggles a menu open and closed:
<div data-controller="menu">
<button data-action="click->menu#toggle">Open</button>
<ul data-menu-target="list" class="hidden">
<li>Item one</li>
<li>Item two</li>
</ul>
</div>
// controllers/menu_controller.js
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["list"]
toggle() {
this.listTarget.classList.toggle("hidden")
}
}
No manual querySelector, no event listener boilerplate — Stimulus handles the wiring automatically when the element appears in the DOM.
How it works in this repo
Controllers live in _assets/js/controllers/ and are registered in _assets/js/app.js. esbuild bundles everything into assets/app.js at build time.