React is 200KB of dependencies for a contact form. HTMX is 14KB and uses HTML you already know.
HTMX lets you build dynamic web apps without writing JavaScript. Instead of onClick
handlers and state management hell, you add HTML attributes like hx-get
and hx-post
to make AJAX requests.
Carson Gross released this in 2020 after getting fed up with the JavaScript ecosystem. Started as a side project, now companies like GitHub and 37signals are using it in production. Turns out a lot of developers were as tired of React's bullshit as Carson was.
The catch? Every click hits your server. Make sure your backend can handle it or your users will hate you.
How It Actually Works
HTMX turns any HTML element into an AJAX trigger. Click a button? It posts to your server. Server returns HTML? HTMX swaps it into the page. That's it.
Instead of sending JSON back and forth like SPAs, your server returns HTML fragments. No client-side templating. No state synchronization headaches. The server controls everything, just like 2005, but with better UX.
Except when it doesn't. I spent like 6 hours, maybe more, debugging some form that just wouldn't submit. No error messages, no console warnings, just nothing. Turns out CORS was blocking requests and HTMX was failing silently. The server logs just showed Access to XMLHttpRequest blocked by CORS policy
. Spent forever thinking I'd screwed up the HTML before I checked the Network tab.
Here's The Most Basic Example
<button hx-post=\"/api/like\" hx-target=\"#like-count\" hx-swap=\"innerHTML\">
Like this post
</button>
Click the button → POST to /api/like
→ server returns <span>42 likes</span>
→ HTMX finds the #like-count
element and replaces its content. No JavaScript, no event handlers, no bullshit.
The 14KB library handles DOM updates, request management, and all the AJAX plumbing you don't want to write. Until it breaks and you're staring at empty responses wondering what went wrong.
Bundle Size Reality Check
HTMX is 14KB gzipped. React starts at 30KB for "Hello World" but grows fast once you add routing, state management, and the 47 packages you actually need in production.
Performance benchmarks show HTMX apps load faster initially, but every interaction hits the server. Fast initial load, slower clicks. Your users will notice the delay if your backend is garbage.
HTMX 2.0: What Changed
HTMX 2.0 shipped in June 2024. The big changes:
- IE11 support dropped - Finally. Nobody cares about IE11 in 2025.
- Extensions moved to separate repo - Less core bloat, faster releases
- Security fix -
selfRequestsOnly
now defaults to true, preventing cross-domain requests - Better module support - Works with ESM, AMD, CJS without hassle
Most existing HTMX 1.x code works unchanged. The breaking changes are small and well documented. Check the complete changelog for full details.
But here's what they don't tell you: upgrading from 1.9 to 2.0 completely fucked our file upload feature. Took me and Jake most of a day to figure out that the new selfRequestsOnly
default was blocking uploads to our CDN. Classic "backwards compatible" upgrade that breaks production at 2pm on a Friday.