Stimulate your Rails App Using Stimulus!!

Tired of JQuery/Plain Js? Try Stimulus

Abiodun Olowode
6 min readAug 11, 2021

Over the years, in order to include the dynamicity that Javascript brings into every application in terms of DOM manipulation, many ROR developers looked to JQuery. In 2018, DHH, the creator of Ruby on Rails, published a new JavaScript framework called Stimulus and since then, one of the most popular descriptions of Stimulus has been that it is “the JavaScript framework with modest ambitions”.

As stated in its documentation, Stimulus was designed to enhance static or server-rendered HTML — the “HTML you already have”. It is a rare occurrence to read a slice of HTML that has an external JavaScript file for its event handlers and tell exactly what the handlers would do at each point; on the other hand, with Stimulus, you can read a slice of HTML and tell exactly what is going on.

It works with a few concepts, namely:

  • Controllers
  • Actions
  • Targets

Looking at that list, what do you see? Separation of concerns, eh? I love, love it 😃! We’ll cover how these work together to add beauty to your Rails app while keeping your code less verbose, clean, and more readable. Enough of that talk, let’s write some code.


My app currently uses Rails 6.1 , and as a result, webpacker and yarn are already installed. To install Stimulus, we use the following command;

rails webpacker:install:stimulus
Stimulus Installation

As seen in the image above, some appending is done to application.js to import the controllers, and new files and folders are created within the javascript folder. One thing to note is that the controllers folder created here is not related to the traditional controllers folder created in the Rails app folder; they only bear the same name.


Let’s explore the stuff that came with our installation. In our app/javascript/controllers/hello_controller.js file, we’ll find some commented-out HTML. Let’s move that HTML to our html.erb file. This can be whatever file you choose in your app to display on the server.

On server reload, this should be displayed.

What in heaven’s name just happened 😕? Let’s break it down.

  • The Controller: A controller file named hello_controller.js exists in our controllers folder.
Hello Controller

Here, a class is created and exported. Within this class, a static array is defined which contains the targets of this controller. As seen, we have an output target defined as "output"; this means that we can henceforth refer to this target as this.outputTarget. If we include another target "showName", we would refer to it within the class as this.showNameTarget; a good practice would be to name targets according to what they should or do display, in order to aid code readability. Within this class also lies a connect function which is invoked on the connection of the controller in question to the DOM; this function assigns the text content of Hello, Stimulus to the output target.

  • The HTML: Within the HTML file, we have an encapsulating div which possesses a data-controller attribute. This is where the name of the controller to be used is specified. As seen, the value of this attribute is "hello" , connecting the div to the hello-controller . Also, recall that we have an output target within the controller that should display a certain text, this target also has to be specified within the div, using the data-target attribute. In our html.erb file, its value is "hello.output", meaning the output target of the hello controller. It is important to note that in future versions of Stimulus, the data-target attribute will be deprecated and we are urged to replace it with data-controllerName-target = “targetName".

And just like that, we got Stimulus working 💃. Not so fast though, let’s add some code of our own 😄.


It all starts with HTML. What can we build? Let’s build a simple app, within which we determine by how much we would like to reduce or increase a number.

Html for Calculation using Stimulus

As seen above, I have created a div and added a data-controller attribute to connect it to a certain controller named calculate . I make it a habit to write my Html before creating my controller; this helps me keep my code readable, as I can ensure no one needs to see my controller to understand what is going on. Within this div , I have added the following:

  1. A data-target attribute to the h3 tag that refers to the current value of the calculation. This is where the computed value will be shown.
  2. A data-target attribute to the input tag that refers to the addend value. This is the value that we would type in for addition or subtraction from the current value.
  3. A data-action attribute to two buttons that carry out the add and subtract actions.

Yes, we’re encountering actions for the first time but they are pretty easy to understand.

The data-action value click->calculate#add is called an action descriptor. This particular descriptor says:

  • click is the event name
  • calculate is the name of the controller
  • add is the controller class method to be invoked


Creating the corresponding controller should be easy, seeing that we already know our methods and target names. In app/javascript/controllers/calculate_controller.js , we add the following:

Calculate Controller

Seeing that the controller is a JavaScript class, we make use of getter methods to get the values of the targets. We also include the add and subtract methods which append the newValue to the currentValue target.

Calculator using Stimulus

Did you notice that weird NAN result? When our input is empty, its value is "" , and ParseInt("") results in NaN(Not a number) . There are several ways of handling this, but here, we’ll handle this within the get addend method, by returning 0 when the input is empty.

The get-addend method rewritten

This fixes our NaN problem and our “calculator” works as expected.

Manipulating an existing HTML document can range from adding a CSS class when certain actions are performed, determining the content of an element, clearing a form after the submit action, to rearranging elements in groupings. Whatever your use case is, Stimulus has got you 🍷.

I strongly recommend the Stimulus Handbook if you would love to delve deeper.

Thank you for reading!



Abiodun Olowode

An Avionics Engineer turned Software Developer with an unquenchable passion for explaining programming concepts.