A transition from VueJS to htmx + Alpine.js

Web pages overload JavaScript,
a harmful force
User frustration grows

VueJS

Nowadays, writing frontend applications even for fairly simple apps might involve complicated and demanding technologies. A few frontend frameworks like React, VueJS, and Svelte became de-facto standards and the go-to choices for any modern website.

When I started configset project a year ago I've chosen VueJS/TypeScript stack due to extensive usage at my previous job. At the start, things were pretty simple, but I've released that additional NPM packages are buggy within the infrastructure, had last commits a few years ago, and not all features were supported by Intellij Idea easily. Some NPM packages started to conflict with each other (dependency hell), and VueJS decided to move from 2 to 3 versions reminding me of the Python upgrade spanning many years.

Most SPA frameworks also require at least some kind of dependency management, client routing, and a local web server for hot reloading. Additionally, the application state should be managed carefully to avoid unexpected behavior when a user navigates from one page to another.

In the end, I've realized that I'm basically moving backend logic from Kotlin to TS for mostly no reason. Things which is simple on the backend or MPA back in the day now require a lot of effort. Productivity was starting to drop quickly and some fresh breath was required.

Next approach with htmx and Alpine.js

After a few days of evaluating different technologies with the simpler development process, I dove deeper into HackerNews discussions of Hotwire library. Although I've found the API a bit complicated the approach reminded the old days with jQuery and how productive it was in most cases.

Then some random devs pointed me to Htmx and I was hooked in the next 10 minutes after reading the documentation. The same happened for Alpine.js as I had to make some reactive changes on a few pages and implement autocomplete widgets.

As an experiment, I rewrote the whole application using these libraries and was impressed by the results. Overall experience was similar to the old times but flexibility and modern browser APIs made development much easier than before.

From an architectural perspective, the app was moved from SPA to MPA. Controllers started to return HTML pieces instead of JSON payloads. Some people might say that it's a downside in the case of mobile applications but the picture is more complicated. Most of the time, the JSON returned to the desktop app is more heavyweight and includes additional entities.

After a while, I created the following PR which shows 5x fewer lines even though functional tests were written to cover frontend functionality using Selenide lib.

Conclusion

Without any doubt, I can recommend taking a precise look at the htmx/Alpinejs stack. There are some exceptions like truly frontend "applications" like messengers for example but in 95% of cases, it is worth trying.