For the past 3 years I had been working on a Rails app with an Angularjs 1.5 front-end (SPA); I didn’t love it. It was much more complex than it needed to be. Our front-end permission management was CanCan implementd for the front-end that would interpret our backend’s CanCan permission object passed to it as JSON. The routing rules used a lot of regular expressions. The pages had deeply nested Angular controllers. The Angular templates were dozens and dozens of Rails view partials buried deep inside various directories. I would often fantasize about deleting the whole thing and replacing it with straightforward HTML. Most of the functionality would have been the same.
However, after using Stimulus for a couple of months I realized that it wasn’t for me for a variety of reasons, including:
- There is nothing in the Stimulus documentation about how to test it. I tried to work out some strategies on my own, but nothing was particularly satisfying.
- There is not a lot of documentation in general. For example, it took me a fair
amount of searching to discover that they use “
--” in their naming for subdirectories. I don’t think it is in the documentation still.
- Putting all of your state in the DOM is tricky. If you have anything that modifies the DOM (for example, we had something that toggled between an “edit” and “view” mode) you could clobber your state; taking state out of the DOM is one of early arguments for Backbone.
- There is no easy way to coordinate or message between controllers, especially nested ones. One of React’s key features is that components can easily pass information to their child components.
- Stimulus disconnects functions from their parameters. You call a function and then it
has to search for the applicable
data-attribute in the DOM.
- Their naming scheme is cumbersome, e.g.
data-controller="using-a--sub-directory" data-target="some--nested--target-has-a.function". Everything is location-in-your-code-file-structure based.
- It was hard for me to get reusable pieces of code. Because nesting controllers seemed to make things complex, I stopped trying to make them work together and I just started making a controller per page.
A lot of my frustrations with Stimulus stem, I think, from my differences from how David Heinemeier Hansson works. I’ve listened to several of his interviews, including recent ones about his Hotwire approach. For example:
- He has a front-end team who can write custom code for him.
- He is focused on Basecamp and Hey
- I work on products that don’t necessarily have the same needs as Basecamp or Hey
About the time I was hitting peak frustration with Stimulus, Vue released version 3. I’ve found that it addresses my frustrations well:
- There are official testing libraries for Vue and with a lot of documentation.
- Vue has several strategies for state management and you don’t have to put state in the DOM.
- Vue has support for passing data between components as well as support for emitting and listening to events.
- Vue makes it clear what parameters are being passed to functions.
- Vue has a lot of naming guidelings, but what you name things is much more flexible.
- Vue encourages code reuse through “composables” (very much like React’s hooks) and components.
The part of Vue that I like the best is that it is a “progressive” framework. That is, I can use it for “sprinkles” at one end or a full single page application at the other. I can write HTML first and then use it for “the HTML I already have.”