Introduction
Hello friends!
We all have to agree on one thing, JavaScript is the king of the web. It is very true that it is the undisputed language that powers over 98.7% of websites, making it the dominant language for web interactivity. You can get so far with plain HTML and CSS when working on your websites. You will however want to have some reactivity on your website. Imagine without JavaScript in your website, you may not be able to implement features such as changing content on the DOM.
As Ruby on Rails developers, we often prefer server-side rendering for speed and SEO benefits and at all costs, we try to reduce the reliance of JavaScript on our applications and rely on server-side rendering of content and sending it to our views to be shown to the client side. This has multiple advantages as this approach allows for pages to load quickly and be indexed by search engines without requiring JavaScript to render content. This is however still limiting and thus need for JavaScript to add that pop to our application reactivity.
This is where Stimulus.js comes in. It is a lightweight JavaScript framework that adds interactivity to HTML designed to enhance static or server-rendered HTML by connecting JavaScript objects to elements on the page using simple annotations. Let this not be confused with Turbo, Turbo focuses on enhancing client-side interactivity by handling page updates, while Stimulus is more focused on managing client-side behavior and adding interactivity to HTML elements.
This article will give you a general overview of Stimulus, covering its features, explain why Stimulus is useful, especially in Ruby on Rails, and give a comparison with other libraries such as React or Jquery. In a future article, we will cover how to set up and use Stimulus in your Ruby on Rails applications.
Stimulus JS deep dive
We earlier mentioned about JavaScript objects. In Stimulus, these JavaScript objects are called controllers. Stimulus uses data-controller
attributes to continuously monitor the pages. For each attribute, Stimulus looks at the attribute’s value to find a corresponding controller class, creates a new instance of that class, and connects it to the element. I would like you to think of it this way: just like the class attribute
is a bridge connecting HTML to CSS, Stimulus’s data-controller
attribute is a bridge connecting HTML to JavaScript.
Stimulus JS core concepts
Stimulus JS builds on controllers with three key concepts: actions, targets, and values. Let’s discuss the further:
1.Actions, which connect controller methods to DOM events using data-action
attributes. Actions allow you to specify what action to take when eg a button is clicked. As an example, assume that you have a controller called hello_controller
that has a method called greet
, and you would like to connect that greet
method to an HTML button, your action would look similar to this:
<button data-action="click->hello#greet"> Greet </button>
where the data action is a click event and that maps it to the greet
method in the hello controller.
2.Targets, which locate elements of significance within a controller. Assuming that you have an input field and you would like when you click the button, the value that is in the input field will be captured and that value will be used somewhere else, this is where the data-<controllerName>-target
attribute comes in. For example, we have our input field, we may want to reference this value as follows:
// Our views
<div data-controller="greet">
<input type="text" data-greet-target="name" placeholder="Enter your name">
<button data-action="click->greet#sayHello">Say Hello</button>
<p data-greet-target="output"></p>
</div>
// Hello controller
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static targets = ["name", "output"];
sayHello() {
this.outputTarget.textContent = `Hello, ${this.nameTarget.value}!`;
}
}
In the code shown above, the Stimulus controller "hello"
defines the nameTarget
and the outputTarget
to reference the HTML input and paragraph. It then updates the paragraph with a greeting message when the button is clicked.
3.Values, allow you to store and update dynamic data within a Stimulus controller using the data-*
attributes. They automatically sync between the HTML and JavaScript, making it easy to manage dynamic data inside Stimulus controllers without manually handling DOM updates. A good example is using values to create a counter that increments or decrements when a button is clicked.
Phew! That was almost a lot of technical content on Stimulus JS, right? Ok, let's take it easier now.
Why anyone should be using Stimulus.js in their applications
We have so far seen what Stimulus is, and had an understanding of its core features. But why should you want to use it anyway? Let’s explore more below:
Can help you with basic interaction enhancement. Take an example of when you want to implement a toggle button functionality in your website.
Form input handling. A great example is the sample I shared earlier when covering the stimulus js concepts (Actions, targets, values).
Fast and lightweight. As compared to similar libraries such as React, it is lightweight and minimal making sure that your application does not experience any lags due to heavy packages.
It has a seamless integration with Ruby on rails. Stimulus is designed to easily work with Ruby on Rails, especially alongside Turbo, and does not affect the existing backend structure.
Has automatic element identification - uses data-targets to reference elements within a controller, reducing the need for manual
document.querySelector
calls and keeping JavaScript neatly organized.Stimulus allows for progressive enhancement of your web applications' client views. It works on top of server-rendered pages, thus ensuring that the core functionality remains intact even if JavaScript is disabled, This improves accessibility and SEO of the web pages.
Despite using Stimulus.js showing real tangible benefits to our applications, they also have some serious considerations that are worth factoring in when using Stimulus over other libraries such as React or Vue.
Stimulus may not be well suited for applications that are very complex and need single page (SPA) functionalities. If your app requires complex state management, virtual DOM updates, or client-side routing, you may need a framework like React or Vue.
The fact that Stimulus is tightly coupled with HTML and relies heavily on the data-*
attributes in HTML, leads to having the code become cluttered if not managed properly. This is especially true in large applications.
While this might not be necessarily true for everyone, however, the syntax that Stimulus uses is not really intuitive at first glance and requires additional reading to try and have a grasp of the syntax to understand the moving parts. This extra layer of complexity might not really suit everyone and they may find it hard to start working on it quickly.
One of the determining factors of the use of a tool is usually the community behind it. Unlike other libraries such as React, Stimulus has a relatively smaller community backing it which would bring a challenge in finding resources or even help when you run into a challenge. You however need not worry because I am here to bridge that gap! 😄
Conclusion
Just like any tool out there, it has its strengths and its weaknesses. In my own opinion, Stimulus is an amazing tool that I believe everybody should be using especially in their Rails applications to add some reactivity to their pages. Stimulus features such as reusable components make it an attractive tool allowing you to define a feature once and reuse it multiple times allowing you to stick to programming principles such as DRY and KISS.
In my next article, we shall go deeper into the technical bits covering a practical demonstration of how to use Stimulus JS in your Ruby on Rails applications.
That wraps up this introduction to Stimulus. I hope you found it insightful, and I look forward to sharing a hands-on guide in the next article.
Top comments (2)
Great Stuff! :) <3
Thank you @simongideon for the positive feedback. xD