Stimulus
02 / 02

Values, Classes, Lifecycle & Hotwire

Values, Classes, Lifecycle & Hotwire

Typed Values

export default class extends Controller {
  static values = { count: Number, active: Boolean }

  countValueChanged(newValue) {
    console.log('count is now', newValue)
  }
}

Reads/writes data-[controller]-count-value with automatic type coercion, plus an optional changed callback — no manual parseInt()/JSON.parse(). Because the value lives in the DOM, a Turbo-driven HTML update naturally keeps the controller in sync with zero extra wiring.

Classes — Decoupling CSS from Behavior

static classes = ["active"]
toggle() { this.element.classList.toggle(this.activeClass) }
// reads data-[controller]-active-class instead of hardcoding a class name

Lifecycle

connect() { /* element entered the DOM — init here */ }
disconnect() { /* element removed — clean up listeners/timers here */ }

Important with Turbo, since page content can be swapped without a full reload — disconnect() is the cleanup hook when a controller's element disappears.

Hotwire: Turbo + Stimulus

Turbo Streams let the server send an HTML fragment that swaps into a specific part of the page — no full reload, no client-owned state model. Stimulus then handles remaining small interactive behavior on that fragment. Tradeoff: great for sprinkled interactivity on mostly server-rendered apps; a full SPA framework is often a better fit for deeply interdependent client-side state (a rich dashboard, a collaborative editor).

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

Start free