Stimulus.js overview

Aug 19, 2020

What is Stimulus and how is it different to other JS frameworks?

Stimulus is a JavaScript framework by Basecamp (the creators of Ruby on Rails) that provides a refreshing and simple alternative to the intense complexity of modern JavaScript approaches.

Unlike contemporary frameworks like React or Vue, it’s not concerned with rendering HTML via some templating mechanism but with augmenting it with behavior only when needed.

When used together with Turbolinks (also by Basecamp), Stimulus can provide you with most of the benefits of single-page applications (e.g. faster UIs, fluid user experience) without the inherent complexities.

You can read more about its origin and motivation in The Origin of Stimulus.

The three core concepts

Stimulus has three core concepts:

  • Controllers – These are JavaScript classes that encapsulate a particular part of your application and contain all the logic to bring your HTML to life.
  • Actions – Event handlers that typically respond to user events such as button clicks or form submissions.
  • Targets – Properties of controllers that map to DOM elements.

Connecting DOM element to Stimulus controller

We can use the data-controller attribute on an DOM element to connect it to a Stimulus controller.

<div data-controller="hello">
 // ...
</div>
// src/controllers/hello_controller.js
import { Controller } from "stimulus";

export default class extends Controller {
  // ...
}

Handling DOM events with actions

<div data-controller="hello">
  <input type="text">
  <button data-action="click->hello#greet">Greet</button>
</div>

Clicking the ‘Greet’ button will now invoke our Stimulus controller’s greet method.

// src/controllers/hello_controller.js
import { Controller } from "stimulus"

export default class extends Controller {
  greet() {
    console.log("Hello, Stimulus!", this.element)
  }
}

Mapping DOM elements to Controller properties

<div data-controller="hello">
  <input data-target="hello.name" type="text">
  <button data-action="click->hello#greet">Greet</button>
</div>
// src/controllers/hello_controller.js
import { Controller } from "stimulus"

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

  greet() {
    console.log(`Hello, ${this.nameTarget.value}!`)
  }
}

Reference

Lifecycle methods

The following lifecyle methods are available inside Stimulus controllers:

  • initialize() – Invoked once when controller is first instantiated
  • connect() – Invoked whenever the controller is connected to the DOM
  • disconnect() – Invoked whenever the controller is disconnected from the DOM

Data API

Assuming the data-controller tag is set to slideshow, we will have the following methods available inside the corresponding controller:

  • this.data.has("index") – Returns true if the controller’s element has a data-slideshow-index attribute (e.g. <div data-controller="slideshow" data-slideshow-index="0">)
  • this.data.get("index") – Returns the value of the element’s data-slideshow-index attribute
  • this.data.set("index", index) – Sets the element’s data-slideshow-foo attribute to index

Conclusion

Having worked with modern JavaScript-heavy applications for years, Stimulus seems to provide a sane and refreshing alternative that could vastly simplify our codebases.

Not surprising really as most things from the folks at Basecamp tend to be very pragmatic and originate from a need to solve real problems as opposed to being designed in a vacuum by clever techies with too much time!