HTMX and Hypermedia-Driven Apps
The pitch for HTMX is almost aggressively simple: what if instead of your server sending JSON to a client that re-renders it into HTML, your server just sent the HTML? HTMX is a ~14KB library that lets any element make a request and swap the response fragment into the page, so you build interactive apps while keeping state and rendering on the server. A hypermedia-driven app is one that leans into that — the server is the source of truth, and interactions are answered with HTML, not data.
I came to HTMX skeptical, having spent years in SPA land. What changed my mind wasn't ideology; it was watching a CRUD dashboard that had metastasized into 400KB of JavaScript get rewritten into something a single engineer could hold in their head. That's the real story here, and also where the honest limits live.
The core idea in five attributes
HTMX extends HTML with attributes that describe requests declaratively. There's no build step, no virtual DOM, no client router. A button that loads content looks like this:
<button hx-get="/orders/recent"
hx-target="#order-list"
hx-swap="innerHTML">
Load recent orders
</button>
<div id="order-list"></div>
The server responds with an HTML fragment, and HTMX swaps it into #order-list. The vocabulary you'll use 90% of the time:
hx-get/hx-post/hx-put/hx-delete— issue a request on interaction.hx-target— which element receives the response.hx-swap— how it's inserted (innerHTML,outerHTML,beforeend, etc.).hx-trigger— what event fires the request (click,keyup changed delay:300ms,revealed).
That's most of the framework. The mental shift is that your endpoints return presentation, not data — which is either liberating or heretical depending on your background.
HATEOAS, unironically
The "AS" in HATEOAS — hypermedia as the engine of application state — was the original REST vision that the JSON-API era quietly abandoned. In a hypermedia app, the server's response doesn't just carry data; it carries the possible next actions as links and forms embedded in the HTML. The client doesn't need to know that "an order in shipped state can be returned but not cancelled" — the server simply includes a Return button and omits the Cancel one.
This collapses a whole category of duplication. In a typical SPA, business rules about what's allowed live on the server (for security) and in the client (for UI state), and they drift. With hypermedia, the rule lives once, on the server, and the UI is a projection of the current state. I've fixed enough "the button was enabled but the API rejected it" bugs to appreciate that deeply.
Where HTMX genuinely wins
The sweet spot is content- and CRUD-heavy applications: admin panels, internal tools, dashboards, forms, e-commerce, most SaaS. For these, the honest scorecard:
| Concern | HTMX / hypermedia | Typical SPA |
|---|---|---|
| JS shipped | Tiny (~14KB + your fragments) | Often 200KB–1MB+ |
| Logic duplication | Server-only | Client + server |
| Initial render | Fast, server HTML | Depends on hydration |
| SEO | Native (real HTML) | Needs SSR setup |
| Team skills | Backend + HTML | Frontend framework depth |
The productivity gain is real for small teams. One person fluent in the backend language can build and maintain a full interactive app without a separate frontend stack, a bundler config, or a state-management library. There's less to learn, less to break, and far less to ship to the browser — which is a performance story that pairs naturally with progressive web app techniques when you want offline caching on top.
Where it stops being the right tool
I won't pretend HTMX scales to everything. The friction shows up when interactivity stops being localized:
- Rich client state. Multi-step wizards with heavy interdependence, drag-and-drop canvases, spreadsheet-like grids — these want client-side state, and re-fetching HTML per keystroke is the wrong model.
- Offline and optimistic UI. If the app must work offline or feel instant before the server responds, you need client logic HTMX doesn't provide.
- Real-time collaborative editing. Conflict resolution and shared cursors belong in a client with proper CRDTs or OT, not fragment swaps.
- Latency-sensitive interactions. Every interaction is a round trip. On a fast network it's imperceptible; on a flaky mobile connection, a SPA's local state feels better.
There's also a subtler cost: chattiness. A page assembled from many independent HTMX fragments can fan out into many requests. You manage this with combined endpoints and out-of-band swaps, but it's real engineering, not free.
HTMX and the server-components movement
It's worth situating HTMX in the current landscape, because it's not alone in pushing rendering back to the server. React Server Components in production chase a similar goal — less client JavaScript, server-owned rendering — from inside the React ecosystem, with a build-time boundary between server and client components. The philosophies rhyme: both say the JSON-hydration-heavy SPA default was often overkill.
The difference is where the complexity sits. RSC keeps you in a component framework with a sophisticated bundler and streaming protocol; HTMX throws almost all of that out and asks you to think in HTML fragments and endpoints. If your team lives in React and wants incremental change, RSC fits. If you want to genuinely shed the frontend toolchain, HTMX is the more radical, and often more maintainable, bet.
The pattern I'd actually recommend
Default to server-rendered HTML, add HTMX for interactivity, and reach for a tiny client library (Alpine.js or hyperscript) for the genuinely client-side bits — a dropdown animation, inline validation, a modal. Keep endpoints returning small, composable fragments. When one screen truly needs SPA-grade interactivity, build that screen as an island of richer client code rather than converting the whole app.
The trap I keep seeing is teams choosing an SPA framework reflexively for apps that are 80% forms and tables, then paying the JavaScript tax forever. HTMX is a reminder that the browser was a hypermedia client long before it was a JavaScript runtime, and for a huge slice of real applications, leaning back into that is faster to build, cheaper to run, and calmer to maintain. Use it where it fits, and don't apologize for reaching for something heavier where it doesn't.
Resources
- HTMX — official documentation
- Hypermedia Systems (free book)
- MDN — Using Fetch and AJAX concepts
- Roy Fielding — REST dissertation, Chapter 5
- Alpine.js documentation
- HTMX GitHub repository
Frequently asked questions
What is HTMX and how does a hypermedia-driven app work?
HTMX is a small JavaScript library that lets any HTML element issue AJAX requests and swap the returned HTML fragment into the page, using attributes like hx-get and hx-target. A hypermedia-driven app keeps application state and rendering on the server: the server responds to interactions with HTML fragments rather than JSON, and the browser simply swaps them in. This revives the original hypermedia model of the web (HATEOAS) with modern ergonomics.
When should I choose HTMX over a SPA framework like React?
Choose HTMX for content-driven and CRUD-heavy apps — dashboards, admin panels, forms, e-commerce — where interactivity is localized and the server already owns the data. It shines when you want to avoid duplicating logic across client and server and ship far less JavaScript. Reach for a SPA when you need rich offline behavior, complex client-side state, real-time collaborative UIs, or highly interactive canvases.
Does HTMX replace JavaScript entirely?
No. HTMX removes the need to hand-write fetch calls and DOM updates for most interactions, but you'll still use small amounts of JavaScript for genuinely client-side concerns like animations, local validation, or a rich text editor. HTMX pairs well with tiny libraries such as Alpine.js or hyperscript for that sprinkle of client behavior.
Hiring a senior Android / Flutter engineer?
I architect and ship production mobile software — Kotlin, Jetpack Compose, Flutter — for robotics, EV infrastructure, fintech, and real-time systems. Open to remote roles in Europe and the US.
Get in touch →