Engineering

Hotwire: The Fight for a World With Less Javascript

avatar

Miguel F.

Developer

Posted on September 23, 2021

banner

I was introduced to software development during a coding Bootcamp in 2018. Over there, I was amazed by the simplicity of the Ruby on Rails framework, especially the MVC pattern.

It was very simple: the model was in charge of communicating with the database and retrieving all the necessary data. The controller was responsible for responding to user actions, asking the model for the data the user was requesting, and sending it to the view, which was responsible for rendering what the user would see in the browser simple and plain HTML.

Suddenly how the web worked made more sense to me. After a couple of projects, I started to want more interactivity in my websites (after all, I was a user of other products, and the bar for quality was high). That was how I met JavaScript and AJAX. I was fortunate enough to learn JS in the ES6 era, so I was able to achieve most of the things I wanted with sprinkles of vanilla JavaScript. With time, it started to get messier. I learned about REST APIs and Single Page Applications frameworks, but I always felt that it was dirtier than the initial Ruby on Rails simplicity I was introduced to.

I never really dove into the SPA wave; I learned the basics, but for my entrepreneurial venture, Rails was more than enough. Nonetheless, after most of my startups failed, I had the opportunity to work with very talented people who knew the SPA business very deeply. I went through the migration from a Rails monolith to a decoupled Frontend and Backend architecture with them. I would love to say the migration went flawlessly, but I saw how the complexities of the new architecture affected everything from the product itself to the development and engineering process in a small team like ours.

I experienced firsthand the problems with cache when a new release was out and the user did not refresh the page: the slow performance of the first print due to the need to load a big chunk of JavaScript on the first request, the complexities of managing state, the increased difficulty of debugging issues between two codebases and the decrease in deployment speed. At the same time, frontend engineers waited for the backend engineers to perform a change. It was messy.

On the other hand, I was closely following Rails development. I saw how Rails stayed on the sidelines when frameworks like React and Vue started to emerge. Instead, they launched Turbolinks, but that did not go as well as expected. Lots of Jquery code broke. They kept working on it and improving it, and after that, they launched Stimulus JS, a great minimalistic framework that paired beautifully with Turbolinks (I adopted it very early on). But still, if you wanted a very interactive interface, you ended up writing way too much custom JavaScript. But at the end of 2020, things changed. With the release of Hotwire, the puzzle was completed. The best of the Rails framework without sacrificing any interactivity on your apps and all of this with 80% less Javascript writing than usual. Mind-blowing!

So how did they achieve such a fantastic result? The reality is that, as with any great innovation, the process was very iterative. All previous attempts of avoiding Javascript complexity finally paid off. To understand this, let’s try to explain the foundations of the most basic concepts of Hotwire:

It is the heart of Hotwire; most of the magic is here. Turbo provides four complementary techniques that help you speed up page changes and form submissions without writing any custom JS, divide complex pages into components, and stream partial page updates over WebSockets.

Everything starts with Turbo Drive (AKA Turbolinks), which is an interceptor for all link clicks and form submissions, that instead of reloading the page, performs requests in the background and then replaces the body (and merges the head) of the document with the returning HTML from the server. This single approach increases the page-level navigation speed a lot because you do not have to reload all the assets, and the speed at which a browser can process HTML is very similar to the speed at which it can process JSON.

For the pages that you do not want to reload completely, you now have Turbo Frames. They work similar to Turbo Drive, but instead of replacing the complete body, you have the ability to encapsulate small parts of the document that can perform individual requests to the server and replace only the content of the matching frame. For example, you can replace an edit button with the form for editing, using the same template for the edit form as if you were visiting the editing page instead. An approach that works great with HTTP/2 and caching.

Turbo Frames are great when we work with direct interactions within a single frame, but what about when we need to update other parts of the pages outside of the Frames? Well, then we can use Turbo Streams. This technique allows us to stream HTML changes to any part of the page in response to updates sent over a WebSocket connection.

These three concepts can take you far, but sooner or later, you will need some customization, and that is what Stimulus JS is for.

Stimulus: A JS framework for the HTML you already have.

Stimulus allows you to connect JavaScript objects to elements on the page using simple annotations. You know that moment when you add a CSS class and the element magically changes position, shape, or color. For me, Stimulus is the same concept but with Javascript instead of CSS. You just need to link your existing HTML with it, and then the magic happens, no query selectors and no need to generate the whole DOM dynamically from Javascript itself.

The most exciting part of all is that it monitors the DOM for changes. For example, if a Turbo Stream was sent or the content of a Turbo Frame changes, the newly added HTML will connect with its corresponding Stimulus controllers and add the needed functionality immediately. No page reload is needed, and no need to listen for fancy Turbolinks load events.

Conclusion

The development of Hotwire and the enhancements coming to the Ruby on Rails framework are both exciting and refreshing. In a way, it feels like the first time I was introduced to the MVC pattern, a very simple yet powerful approach for building web (and now even mobile) applications without the well-known complexity of building a compelling SPA.

I encourage anyone reading this, to try these new technologies and rethink the need for complex front-end frameworks. Finally, another path can take us to the same level of interactivity with a fraction of the complexity. It is on us to keep fighting for a world with better frameworks and techniques.

I recommend this approach to you, especially if you have a small development team or you are an indie hacker building stuff on your own. I guarantee you can go 10x faster this way, and you will end up with much better user experiences because of this.

What do you think? Is the web going to be built with more or less JavaScript in the future?

Join 2000+ Founders and Developers crushing their businesses and careers with monthly advice. You can also follow us on LinkedIn , Twitter & Instagram!

Share on