Stimulus
01 / 02

Controllers, Targets & Actions

Controllers, Targets & Actions

HTML Stays the Source of Truth

Unlike React/Vue where JS renders the UI from state, Stimulus adds small bits of behavior ON TOP of server-rendered HTML — the DOM itself is the source of truth. Created by Basecamp, part of "Hotwire" alongside Turbo.

A Basic Controller

<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>
// hello_controller.js -> identifier "hello" (suffix stripped, underscores -> dashes)
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = ["name", "output"]

  greet() {
    this.outputTarget.textContent = `Hello, ${this.nameTarget.value}!`
  }
}

data-controller connects the class; static targets generates this.nameTarget/this.outputTarget (or the plural nameTargets for all matches) — no manual querySelector(). data-action="event->controller#method" wires DOM events to methods declaratively; click is the default for a <button> so it can often be shortened to data-action="hello#greet".

Registration

application.register("hello", HelloController)
// many Rails/importmap setups auto-register based on file naming convention

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free