Why HTMX is far superior to React and NextJs
Tags: htmx, javascript, website, webdev
Published: 2024-07-09 01:48:21

On Anuntech we have the challenge to create an ERP, and for the ones that already worked with it, know that ERP can be one of the more complex types of software to create (and use, god have mercy of SAP users).

To avoid the complexity to use, we wanted something similar to PlayStore: You have an infinity of modules to enable, you can choose the ones that you need or choose a "business template" to fit your needs, and with our goal in mid, came or first problem: Choosing the frontend tool.

## React

So, to create any website, we need a framework, everyone knows this unquestionable truth. And as any other person, the first framework that came in mid was React, the most used, most loved, most incredible, of the billion JavaScript frameworks out there.

React is nice, it gave us:

* The ability to create components and reuse them, keeping a standard and avoiding duplication
    
* The ability to create high-interactive frontends (now our forms can have inline validation to know if your email has an `@`!)
    
* A way to decrease our server costs (very important for every startup), by running everything on the client
    

But react itself has lots of problems:

* It bundles EVERYTHING together, and for a product like Anuntech, that will have hundreds of different things, the bundle would have the same size as an AAA game.
    
* It's heavy *af*, uses virtual DOM to create and manipulate things, what is terrible for weak pcs, and guess what? All our clients have weak pcs.
    

So we had to think a little more: If we can't use React, what is our next choice?

## Next

Of course, the natural evolution of React, Next!, React is already perfect, but with Next it's on another level of *perfectness*! There's no way that it will not work:

* Next bundles each page separately, and each page only has the required dependencies, this will keep the bundle at an acceptable size
    
* It still keeps all the *good stuff* that React has: high-interactive frontends
    
* Has many built-in optimizations for images, videos, etc.
    

But Next has even more problems than React:

* We lose the pro of not spending with servers, now we need a server to run our frontend
    
* It still is heavy *af*, it uses react to build things, and worst, it builds on the server too
    
* Know that we have client and server, we must keep the user logged on both, and it must be able to do authenticated requests to our APIs both on server and client, which increases the complexity A LOT.
    

So we began to realize that the problem wasn't the framework, but the whole JavaScript ecosystem.

## War against JavaScript

The JavaScript ecosystem has innumerable flaws:

* It's extremely complex for someone with 0 experience to work with JavaScript tools. They all require 10 other tools to work, and you MUST learn them all to do even the basics.
    
    * If we keep using Next, to hire a frontend developer, they would be required (or we would be required to invest time and money training they) to know: HTML, CSS, JavaScript, TypeScript, Tailwind, React, NextJs, Hookform (or whatever library they will be using 5 minutes from now), State management with React, Server components, the brand-new awesome way to write react that will change next month, the brand-new way to right next that will change next month, and so on. The list never ends, and all of it to do the basics.
        
* It requires LOTS of dependencies, and each dependency has even more dependencies. The JavaScript ecosystem has a serious problem with wanting to delegate even the smallest problem to someone other than themselves. It brings security risks in a scale never seems before, and they seem to not learn a thing with events like [PolyfillJs](https://snyk.io/blog/polyfill-supply-chain-attack-js-cdn-assets/) and [Coa](https://www.bleepingcomputer.com/news/security/popular-coa-npm-library-hijacked-to-steal-user-passwords/).
    
* Builds 1 bundle with your custom code and all the libraries that you use, what makes it impossible to cache the libraries on the client to avoid having to download them again if you change your custom code.
    
* JavaScript is terrible anything else than manipulating the DOM, using it on the server is something that we want to avoid at all costs. Has terrible performance, terrible memory management and terrible long-term life.
    
* The ecosystem is more unstable than the humor of someone with borderline disorder, JavaScript developers can't stand having one `;` that they don't like, or they will create their own thing from scratch, and guess what? It will become the new standard, god knows why. Every couple months the way to write React changes, or the way to write Next changes, or the way to manage states changes, or manage forms, or do styling, ALWAYS something is changing and nothing never has the minimum amount of stability nor standard. It forces the developers to always learn the same thing in a different way, and your codebase will be outdated on the moment that you finish writing it.
    

And for our specific case, we also had more problems:

* In our case, as we have microservices for the APIs, with Next/React we have to maintain gRPC (for server-server communication) and REST (for client-server communication), which makes the backend team maintain 2 delivery systems, 2 API documentations (.proto and openapi specs), and make the services available on the internet for the client to hit them directly, what also make us to have to validate the user authentication and authorization on every service.
    

And because of all the problems that we had on our place, we decided to take the things drastically. Instead of looking in one single solution and try to make it work, changing it a bit to see if we manage to fit a square into a triangle, we choose to turn 180° and look for extreme alternatives, avoiding the root of all these problems: JavaScript.

## HTMX

As probably many of the people that knows HTMX, I heard of it firstly from [Primeagen](https://www.youtube.com/@ThePrimeTimeagen). At first, I hated it. My first though was "Nice, coming full circle back to PHP", but after some review on the solution and after learning more about the idea, I saw that HTMX is exactly what we are looking for.

HTMX solves all our problems and gives us even more power:

* It is SSR, which solves the bundle-size problem.
    
* It provides interactive for the most important parts (partial page reloading), and allow us to create our own custom basic script for things that it cannot do (like validating form fields).
    
* Allow us to choose the language that we want to run it, we are no longer stuck at JavaScript.
    
* Has 0 dependencies.
    
* It's only 1 file of JavaScript, very easy to understand and well documented. If the maintainers decide to not maintain it anymore, we can maintain it ourselves, as opposite of React / Next, where we are stuck with them and their decision to where to go.
    

## The final solution

So, as we were already writing our backend services in Golang, we choose to write our frontend in Golang + HTMX + Templ, with Tailwind and DaisyUI for styling. Here are the main reasons:

* As the backend team is already having to communicate between services, they are already maintaining a library for each service that exposes the "API routes", what makes it a lot easier for the frontend to integrate with the services: Just use the libraries instead of building an integration from the scratch.
    
* The selling point of "JavaScript on the server" also can be used here: Having one language for frontend and backend allows your developers to be full-stack and have less trouble working on both parts of the system (what is a big lie with TypeScript, btw)
    
* The benefits of having one language also affects the DevOps team: With 1 language there's only 1 dev environment to configure (and 1 doc to write about how to configure everything you need), 1 pipeline to maintain, 1 type of machine to configure to run the servers, and so on.
    
* With only SSR, almost zero JavaScript and no state management on the client, the automated tests become a lot easier to write and reliable: Just call the route and check if the text (HTML) returned is right.
    
* Golang is EXTREMELY faster and lightweight than NextJs servers. It allows the devs to have weaker pcs and not lose performance and having to wait 5 minutes to start the server and render a single page, what makes the company able to buy cheaper pcs and save a lot of money.
    
* HTMX allows us to run things in lambdas, something that we don't do at the moment, but hey, it's very nice to have this door open when it was sealed with concrete and 3 inches of steel when working with NextJs.
    

The challenges that we can see coming:

* The good old ID duplication: Too many components can generate components with the same ID, what makes it easily change things that shouldn't be changed. We plan to avoid it, defining a good naming pattern for the IDs.
    

## The conclusion

We are here exploring a new thing: There are not many production apps using HTMX, and probably none of them are as big as we want to become. I'm not sure if we are taking the right decision here, but I'm sure that it's better than using NextJs or dealing with the JavaScript ecosystem.