Sprinkling StimulusJS - Light JS Without Heavy Choices.
Tags: javascript, stimulus
Published: 2019-07-07 17:39:55

---
title: Sprinkling StimulusJS - Light JS Without Heavy Choices.
published: true
description: A dive into using StimulusJS on when it is suitable to use and my experience with it.
cover_image: https://thepracticaldev.s3.amazonaws.com/i/c6d56ej8nbwgnig2e2jg.png
tags: javascript, stimulus
---

# Introduction

In today's state of web applications, it can be hard to choose the right tool to imbue your web pages with bits of interactivity. There is an immense number of options that you can take, but unfortunately, many of them require you to commit to a comprehensive javascript framework. This decision to commit I believe should not be taken lightly especially if you are making this choice for your team/company/business.

The way I often handle these decisions is to not avoid making them at all. Decision fatigue and the stress it brings are real.

In an evasive attitude of risk, I discovered [StimulusJS](https://stimulusjs.org) as a possible option that fits some of the use cases. In this article, I share my experience with it in creating an interactive password input form with requirements being shown as being satisfied or not on user typing and my thoughts on it.

# Sprinkle Stimulus

As the authors mentioned, the goal of Stimulus is to sprinkle pages with JS to make them sparkle. If you primarily have server-side rendered HTML pages and you want to imbue some interactivity on them, then it might be a good fit for your project. Otherwise, you might want to find another tool.

The [core concepts](https://stimulusjs.org/handbook/origin#the-three-core-concepts-in-stimulus) specifically mention that it is mainly meant to bind onto existing HTML and manipulating them. It is not concerned with creating HTML to render like [React](https://reactjs.org/) does.


For instance:
```html
// In Stimulus
<div data-controller="clipboard">
  PIN: <input data-target="clipboard.source" type="text" value="1234" readonly>
  <button data-action="clipboard#copy">Copy to Clipboard</button>
</div>
```

```html
// In React
<pin-input></pin-input>
```

In the Stimulus approach, you'd see all the HTML up front and might avoid having to dig into another file to see what HTML would be. However, this could mean your HTML files can get larger and run the risk of being unmanageable.

# StimulusJS Is Pretty Easy To Learn

As a person who spends most of their time working in the backend, I found that the documentation was clear and easy to digest. I was able to get the main premise of it and enough information to use it fairly quickly. I spent about an hour (or so) with the documentation and was able to be productive with it.

# Building An Interactive Password Input Field With Requirements

In my pursuit of learning, I created a basic password input field that shows the requirements beneath it in an interactive manner. The requirements beneath are toggled to be satisfied or not satisfied upon user input. You can see the source code [here](https://github.com/edwinthinks/stimulus-password-requirements) and test it live [here](https://stimulus-password-requirements.netlify.com/).

A demo gif of it - 
![Demo of password requirements field](https://thepracticaldev.s3.amazonaws.com/i/y7fvk5dfm8htjvb3sfaq.gif)

Here is are snippets derived from the code that demonstrates it working together (with some code removed for brevity):

```js
import { Controller } from "stimulus";

class PasswordInputController extends Controller {
  static targets = [
    "lowercaseLetter"
    // Removed other targets for brevity.
  ]

  connect() {
    this.validatePassword();
  }

  onInput(event) {
    this.password = event.target.value;
  }

  set password(value) {
    this.data.set("password", value);
    this.validatePassword();
  }

  get password() {
    if (!this.data.has("password")) {
      this.password = "";
    }

    return this.data.get("password")
  }

  validatePassword() {

    // Validate lowercase letters
    let lowerCaseLetters = /[a-z]/g;
    if (this.password.match(lowerCaseLetters)) {
      this.lowercaseLetterTarget.classList.toggle('invalid', false);
    } else {
      this.lowercaseLetterTarget.classList.toggle('invalid', true);
    }

    // Removed code on other validations of brevity
  }

}

export { PasswordInputController }
```

```html
<div data-controller="password-input">
  <input class="input" type="password" data-action="input->password-input#onInput"></input>

  <li data-target="password-input.lowercaseLetter" class="password-requirements__requirement">
    At least one lowercase letter
  </li>
  <!-- Remove Code For Brevity -->
</div>
```

The `PasswordInputController` defines the logic that runs in relation to the HTML that it will be bound to. The `Controller` class provided by Stimulus, gives us the ability to have sections of logic to run upon binding via `connect()` and on user input defined by `onInput()` and the `data-action="input->password-input#onInput"` attribute on the input element. A `validatePassword()` function is defined to add/remove the `invalid` CSS class of the corresponding `li` elements via the `data-target` attribute. This function is called initially by `connect()` and also within the setter of `password`.

Through this, I was able to produce a functional password input field.

# Testing?

I found that testing the controllers made via Stimulus was not as simple as I would have liked. 

I initially ran into some issues trying to get the stimulus controllers to run in due to missing `MutationObserver`.  This was remedied by a [post by Hrvoje Šimić](https://shime.sh/testing-stimulus). 

Unfortunately, there are not many resources related to how to testing. However, a [issue](https://github.com/stimulusjs/stimulus/issues/260) had been opened recently to request added documentation on the official webpage.

Admittedly, my struggles with getting the tests setup might be rooted in my inexperience.

# Conclusion

Stimulus is a great tool that can be used to make your HTML pages "sparkle" with interactivity without having to commit to a framework. It was fairly easy and approachable to learn how to utilize the Stimulus.

If you find yourself needing to add a little bit of interactivity onto your predominantly server-side HTML rendered application, you might find salvation in choosing to use Stimulus.