I’ll be presenting at the first BELGRADE.js sessions about my favorite frontend stack. These are my notes for the talk.

Single page applications significantly improved user experience over traditional server-side rendering.

Client requests only the data that is needed to update the page segment in the same process without rebuilding the DOM. A positive impact on server response time (reduced server load), client gets data faster and updates the page in-place. No white page, scroll position maintained. Great!

Unfortunately, all the good stuff came at the expense of complexity and developer experience. As a full-stack developer now I have to maintain a separate codebase and think about state management, routing, SEO, async data fetching…

React didn’t help with any of these issues. I found its ecosystem rather dynamic and complex. Following up with all the state management options (Context, Redux, MobX…) was consuming. Migration from lifecycle methods to hooks on a large codebase painful. JSX and create-react-app didn’t feel right.

So I started looking for a simpler alternative for my personal projects. Ideally, I wanted the dev experience of server-side rendering with the look and feel of SPA. That’s where HTMX and Hotwire fit in. Hotwire 1.0 was fresh release - perfect time to try it out.

hotwire-intro

Hotwire is created at 37signals to power Hey.com email service. I had already followed and admired what they do with Basecamp and Ruby on Rails. Hotwire works well with Rails, but is backend agnostic - use your favorite backend stack. Both Basecamp and Hey are globally popular apps, so I was confident their tech stack is production-ready.

hotwire-landing

Hotwire is an alternative approach to building modern web applications without using much JavaScript by sending HTML instead of JSON over the wire.

The idea is you can have a static page enhanced on the client without writing JavaScript.

No JS Land - Hotwire Turbo

Turbo is the main component of HOTWIRE stack. Turbo uses multiple techniques to enhance static pages with SPA-like user experience.

Turbo Drive 🧙

This is the auto-magic part of using Turbo. When you click on a link, Turbo Drive intercepts the visit, makes fetch request to the link URL and uses response HTML to replaces <body> without re-building the DOM. There is no refresh and white page between page loads, scroll position maintained, so by default we get fluidity of SPA on server-side rendered pages.

Turbo Frames 🖼️

It allows predefined parts of a page to be updated on request. If you have an independent segment of a page, you can make it a frame by wrapping with <turbo-frame> which will capture requests made from inside the frame and update frame contents with the response.

Turbo Streams

You can stream HTML elements (not the whole page) as events to the frontend and react to these events. If one-way connection (server → client) is enough, you can use server-sent events to stream HTML for page updates. Think notifications, messages, etc…

Hello JavaScript - Hotwire Stimulus

Now we have responsive and dynamic site, but you want to make elements interactive without necessarily (you can) reaching the server. Think tooltips, form validations, etc… That’s where Stimulus comes in - a JavaScript framework designed to enhance server-rendered HTML.

Stimulus Controller is a JavaScript object attaches to and interacts with DOM elements. To attach controller to an element, add data-controller attribute with a value equal to the controller’s name.