Skip to main content Accessibility Feedback

Why not HTMX?

One of the most frequent questions I’ve been asked over the last year is…

Have you heard of HTMX? What do you think about it?

Today, I’m finally going to answer that question.

(Spoiler alert: I don’t like it.)

Let’s dig in!

What is HTMX?

HTMX provides attributes that you can use to write interactive HTML components declaratively in your markup instead of separately in a JavaScript file.

Conceptually, I love that! It’s a big part of what I love about Web Components, and why I advocate so strongly for them as the backbone of resilient, maintainable front end.

Quick aside: if you need help setting up, extending, or fixing your front-end architecture, I can help with that!

But in implementation, I think HTMX falls way, way short.

It has all the same problems as other frameworks: a big footprint, vendor lock-in, and seemingly no focus on accessibility.

The Motivations

The HTMX website lists four “motivations” behind the project…

  • Why should only <a> and <form> be able to make HTTP requests?
  • Why should only click & submit events trigger them?
  • Why should only GET & POST methods be available?
  • Why should you only be able to replace the entire screen?

By removing these arbitrary constraints, htmx completes HTML as a hypertext.

So let’s talk about these questions, as well my comments around footprint, lock-in, and accessibility.

A bit footprint

The HTMX website says…

htmx is small

But, frankly, that’s not true.

While the minified and gzipped version of 15.7kb, the actual uncompressed script is 47.8. Smaller than React, sure, but not “small” in my opinion.

Preact weighs less than 12kb without gzipping!

And for that size and abstraction you’re getting stuff that you’re probably not going to use. It’s the Swiss Army Knife problem I talked about yesterday.

Vendor lock-in

This is “the big one” for me. HTMX uses an hx-* syntax for its various attributes…

<button hx-post="/clicked"
    hx-trigger="click"
    hx-target="#parent-div"
    hx-swap="outerHTML"
>
    Click Me!
</button>

That means that once you start using HTMX, you’re looking at a big rewrite if you want to move away from it.

That’s true of any script or library, of course! But using smaller, more focused Web Components to do the same thing means you migrate or update that one component, without a dependency on a bigger library.

And, if you want a button to make a POST request, like in that HTMX example, you could wrap it in a form and have meaningful HTML that has a server-based fallback!

<!-- A Web Component Alternative -->
<ajax-form target="#parent-div" swap>
	<form action="/clicked" method="post">
		<button>Activate Me</button>
	</form>
</dynamic-button>

Accessibility

The documentation includes examples like this…

<div hx-get="/clicked" hx-trigger="click[ctrlKey]">
    Control Click Me
</div>

That div reacts to click events. But a div isn’t focusable, nor does it indicate to screen reader users that it’s interactive.

The HTMX homepage asks…

  • Why should only <a> and <form> be able to make HTTP requests?
  • Why should only click & submit events trigger them?

Some of this stuff is legacy architecture decisions, but some of it is driven by accessibility and how humans and machines interact with each other.

You can’t ignore that stuff just because it’s inconvenient.

By removing these arbitrary constraints, htmx completes HTML as a hypertext.

Is it arbitrary? Maybe, in some cases. But it’s still important.

Valid questions

HTMX does ask some valid questions…

  • Why should only GET & POST methods be available?
  • Why should you only be able to replace the entire screen?

I’d love to see form elements add support for PUT and DELETE methods, frankly.

Is it critical? Nope! You can still do all the same stuff you’d do with those methods without them. It would make things a bit nicer for for talking with APIs, though.

And a browser-native way to implement islands architecture could be interesting. I’m less convinced that’s a critical need for the platform, but I do think it’s a potentially useful addition.

If not HTMX, then what?

Web Components. Hands-down.

You can do all of the same stuff, but in a small, modular, portable way. Web Components work great on their own, and can also be mixed-and-matched with another library of your choice.