Taking a Bet
I hitched my wagon at the time to Ember, since I viewed it as the Rails of the frontend: fully-featured, not controlled by a large company, opinionated, and modern. Participating in the Ember community made me several friends and colleagues who I still keep in touch with. Ember saw some popularity for a few years, but was entirely eclipsed by React.
So, the industry consolidated around React.
Parallel to this, I had joined Gusto in 2016. Gusto had started out on Backbone.js in ~2011 and had made the decision to move to React in 2015. Progress was slow-going, as we didn’t have a team dedicated to the effort. Our efforts to get us off of Backbone.js and onto React were ad-hoc and best effort. We liked the React mental model a bit better, as it prevents a certain class of error that might be easier to make in Backbone.js. React is at its best when it’s forcing the programmer to think about how data flows through the page. Gusto runs payroll, benefits, and HR for small businesses in the US, so the application can mostly be summarized as some of the most complicated forms you might see in a web application. The incidental complexity of payroll and filing taxes can only be reduced so far.
React served us well, but things that were once easy became harder. As we bought more into the ecosystem, simple things began feeling harder. It hit us when adding a single input to a form resulted in a 700-line pull request. Coming from a Rails background, this felt like 690 more lines than we should have needed to write. But, my duties pulled me elsewhere in the company and I began to focus and care less about the frontend of the application.
Starting Something New
My familiarity with React and its ecosystem peaked in 2020. I hadn’t kept up with its development beyond reading Twitter. I thought the push into server-side components was interesting but duplicative for most non-new companies. Nonetheless, React remained what I knew best.
So when I left Gusto mid-2023, we went with React as the means of adding interactivity to our application.1 After a few weeks of building an initial prototype, it was clear that React of 2023 was very different from the React of 2014. The small, discretely mountable components had been replaced by an all-or-nothing approach. It took me some time to figure out how to hack a sprinkling-based approach, since the library seems to really want to drive the entire page these days. Embracing React fully was a non-starter, since the backend was in Rails, the technology that I’ve spent most of my career with.
It was a near-daily occurrence to be fighting React because it was not the one generating the server-side HTML. I only wanted half of what the library had become. It was no longer a gradually-adoptable library, but an all-or-nothing framework. The seed was planted to make a change.
When we hired our first engineer, he brought new expertise to the company. When giving him the tour of our nascent application, I highlighted my struggles with React. He suggested we use StimulusJS, since it fits well to the business we’re building and gels well with Rails.
Normally, a framework change for a young company is a terrible distraction, but we were in a position where there would never be a cheaper time to make the change as today. Without making the change, we’d put ourselves in a progressively more painful situation as we grew. So we made the decision to cut over and were done within a week.
StimulusJS lets you consolidate more application logic and state to the backend. Sure, you might not get the reactivity of client-side state but client-side state is a lie.
Where are we today?
We’ve discovered some of the sharp edges of StimulusJS, mostly around typos in action names. This first felt like a huge regression when coming from a TypeScript world.
After a false start with React in 2023, we’re now on a tech stack that we’re not fighting against and that maps better to our customers’ domain. The result is that we’re able to be a lot more nimble than our competitors, which we think will result in better products for our customers and better business outcomes for ourselves.
Special thanks to Ngan Pham for chastising me years ago to give StimulusJS a try. I blew him off at the time, but he came with receipts when I started writing this post. Lesson: always listen to Ngan.