HTMX vs AlpineJS - Which should you use for your web app?

Date: 2024-01-29 | create | tech | htmx | alpine |

Low-js tools like HTMX and AlpineJS are the future of the web. They allow us to build modern web apps without the bloat of popular SPA frameworks.

I've been researching and experimenting with low-js technologies for the past year, eventually deciding to build my apps with HTMX + F# instead of SvelteKit. I've found the low-js approach to be much simpler while providing all the power I need to build modern web apps.

One of the things that took me awhile to understand (and that I see a good amount of confusion about in the community) is how to choose between low-js tools HTMX and Alpine for your apps. Some guides will use one or the other, others both.

So in this post I want to clarify the differences so you can make the best choice for your web app.

HTMX and AlpineJS are Complimentary

The decision between HTMX and AlpineJS is not an exclusive one. These are not competing tools offering the same functionality (though there is overlap in what each of them can do). Instead, we should view them as complimentary tools.

They work well together because they focus on solving common but different aspects of web app development.

Plus both are fundamental low-js tools meaning they provide these functionalities without unnecessary baggage:

  • There are no build steps (just include it from a CDN)
  • There's minimal JS (mostly in-line attributes)
  • They are easy to compose (you can sprinkle them in where needed w/o disrupting your whole system)

So these work well together which is why you'll see just as many apps using both as you might using just one or using one with a different lib.

Now that we've seen the similarities, let's talk about what each is uniquely good at.

Use HTMX for server interactivity

HTMX - Interactive Islands

Image from Simple Interactive Islands with F# and HTMX

HTMX is focused on making server interactivity simple and powerful. Its unique trait is that it's hyper-focused on Hypermedia controls.

What this means for us is that it controls everything via HTML attributes.

  • You can tell HTML elements how they should behave when a user does something (or an event occurs)
  • It can send requests to a server
  • It can then use the returned HTML to swap out partial pages

This may not seem like much but the ability to do partial page reloads is actually the fundamental thing that SPAs do to feel fast. So HTMX allows you to build the same modern-feeling apps, just simpler, faster, and cheaper.

So when should you use HTMX?

  • When you have control over the server and its responses. HTMX expects HTML returns so you need to be able to modify the server endpoints.
  • When your app runs on data only the server knows about. Any app that persists data (does CRUD operations) does this. But if your thing only does things in the browser (like a JS-based calculator) then HTMX won't help much.
  • When your app doesn't need complex, high speed rendering. HTMX is quite fast. In many cases it's much faster than SPAs when data needs to be read and returned from the server as it skips a whole layer of logic for serialization/deserialization/parsing. But if you're building a video game or something, a network call to the server will not be fast enough so you should reach for a specialized local rendering engine.

HTMX is great for building web apps that require server interactivity - displaying and updating data located on the server. For these cases, reach for HTMX.

Use AlpineJS for client interactivity

While most interactivity (~80%+) you might want in a web app works well with HTMX's SSR HTML approach, it may not be the best tool for everything.

For example, there are some things we might want to build to make the user experience better that doesn't rely on or impact any data the server has. Things like showing or hiding a modal or interacting with a JS library on your web page that only live on the client don't really gain anything from asking the server for information. In fact trying to ask the server for information on things that only live on the client can be quite awkward and slow (network requests are not the fastest thing in the world).

This is where AlpineJS shines and why Alpine (or another lightweight client interactivity library) is often used alongside HTMX.

AlpineJS takes a similar low-js approach allowing you to declare clientside state and functionality in a simple, concise way directly in your HTML. This allows it to play very nice with HTMX as all your minimal logic declarations can be declared and viewed all in one place (Locality of Behavior).

So when should you use AlpineJS?

  • When you have functionality that is clientside-only. The most common example of this is showing or hiding a modal or dropdown. This stuff only exists on client to augment the user experience - the server doesn't need to know about this and it doesn't make sense to wait on a network call for it.
  • When you need to interact with JS libraries on the client. JS has a massive ecosystem so it's likely you will want to leverage some third-party libraries for things like visualizations or drag-and-drops or things like that. For this you might as well use JS for easier integration. Alpine gives you simple lifecycle hooks to make integrations like these simpler.

AlpineJS is great for sprinkling client interactivity in your app with minimal JS overhead. When it doesn't make sense to ask the server for something, AlpineJS can fill in the gaps.


So far I've really been enjoying building web apps with HTMX + Alpine. I've found it allows me to build my web apps faster and cheaper than the SPAs ever did.

Plus it doesn't lock me into a specific technology (like Node) so I can build fullstack apps with F# (my fave language) and HTMX + Alpine for frontend interactivity. This is the power of the HOWL stack (Hypermedia on Whatever you Like).

If you liked this post you might also like:

Want more like this?

The best / easiest way to support my work is by subscribing for future updates and sharing with your network.