HTMX: Server-Side HTML for the Modern Web
HTMX: Server-Side HTML for the Modern Web
HTMX challenges a core assumption of modern web development: that dynamic web interfaces require JavaScript frameworks managing state and rendering on the client. HTMX takes the opposite approach — let the server render HTML, and use lightweight attributes to make that HTML interactive.
It's not for every project. When it fits, it's remarkably elegant.
What Is HTMX?
HTMX is a small (~14KB) JavaScript library that extends HTML with attributes that enable AJAX requests, CSS transitions, WebSockets, and Server-Sent Events — all directly in your HTML markup.
The core idea: instead of writing JavaScript to fetch data and manipulate the DOM, you annotate HTML elements with HTMX attributes that describe what to do when events happen.
A basic example — a button that loads content:
<button hx-get="/api/content" hx-target="#result">
Load Content
</button>
<div id="result">
<!-- Content loaded here -->
</div>
When clicked, HTMX sends a GET request to /api/content and swaps the response HTML into #result. No JavaScript written. Your server responds with HTML fragments, not JSON.
The Philosophy: Hypermedia-Driven Applications
HTMX is built around the hypermedia model of the web — the idea that the server controls application state and sends HTML representing that state, rather than sending raw data that client-side JavaScript transforms into UI.
In a React/Vue/Angular app, the typical flow is:
- Client sends request to API
- Server returns JSON
- Client-side JavaScript processes JSON and renders DOM
In an HTMX app:
- Client sends request to server
- Server processes request, updates state, renders HTML
- HTMX swaps the HTML into the page
The difference is that the server is doing the rendering, the business logic, and the state management — which is where those concerns arguably belong.
HTMX Core Attributes
HTMX extends HTML with a handful of key attributes:
| Attribute | Purpose |
|---|---|
hx-get, hx-post, hx-put, hx-delete |
Make HTTP requests |
hx-target |
Where to put the response |
hx-swap |
How to insert (innerHTML, outerHTML, beforebegin, etc.) |
hx-trigger |
What event triggers the request (click, change, load, etc.) |
hx-boost |
Progressive enhancement for <a> and <form> elements |
hx-push-url |
Update browser URL on request |
hx-on |
Handle events inline |
hx-confirm |
Show confirmation dialog before request |
A search-as-you-type example:
<input
type="search"
name="q"
placeholder="Search..."
hx-get="/search"
hx-trigger="keyup changed delay:300ms"
hx-target="#results"
/>
<div id="results"></div>
Every 300ms after the user stops typing, HTMX sends a GET request to /search?q=<value> and replaces #results with the response. The server renders a <ul> of results and returns that HTML fragment.
What HTMX Does Well
Form-heavy applications: Traditional forms, validation, multi-step wizards — HTMX handles these naturally. The server renders the next step or validation errors as HTML, HTMX swaps them in.
Dashboards with live data: With HTMX's Server-Sent Events support, you can push real-time updates from the server without writing WebSocket client code.
Progressive enhancement: hx-boost converts standard <a> links and <form> elements to AJAX requests, giving you SPA-like navigation with zero markup changes. Works without JavaScript too (degrades gracefully).
Admin panels and internal tools: Where the complexity of a React app isn't justified by the user base.
Server-side rendering with any language: HTMX works with any backend — Python/Django, Ruby/Rails, Go, Node.js, PHP. Your server just needs to render HTML. This is a meaningful advantage for teams that don't want their backend dictated by JavaScript ecosystem concerns.
What HTMX Doesn't Do Well
Complex client-side state: If you need a rich interactive UI — drag-and-drop, complex form interactions, real-time collaborative editing — HTMX starts to feel like fighting the model. The server roundtrip for every interaction adds latency.
Offline functionality: HTMX requires a server. Progressive Web Apps with offline support need client-side data and rendering.
Existing React codebases: If you have a React app, migrating to HTMX is a significant rewrite. There's no incremental adoption path (unlike something like React → Preact).
Heavy data visualization: Complex charts, maps, and visualizations still need JavaScript libraries. HTMX doesn't eliminate JavaScript — it reduces how much you need to write for basic interactivity.
HTMX vs. React vs. Astro
| Approach | Best for | JavaScript | Data flow |
|---|---|---|---|
| HTMX | Server-rendered apps, forms | Minimal | Server → HTML |
| React/Next.js | Rich SPAs, complex state | Heavy | Server → JSON → DOM |
| Astro | Content sites | Near-zero | Build-time → HTML |
These aren't mutually exclusive. Astro can use HTMX for dynamic components. A Next.js app might use HTMX for a subset of server-rendered pages.
Getting Started
Add HTMX to any page:
<script src="https://unpkg.com/htmx.org@2/dist/htmx.min.js"></script>
Or install via npm:
npm install htmx.org
Then start adding hx-* attributes to your HTML. The HTMX documentation is unusually well-written and includes a good set of examples.
The Simplicity Argument
The strongest case for HTMX isn't performance or specific features — it's simplicity.
A typical React CRUD application involves: React components, state management (Zustand, Redux, or Context), an API client, TypeScript types for every API response, and often a separate backend with its own API. This is a lot of moving parts.
The equivalent HTMX application involves: your server-side language (rendering HTML), and HTML with HTMX attributes. No client-side state management. No API layer (you return HTML, not JSON). No serialization/deserialization.
For teams building internal tools, admin panels, or applications where developer experience matters more than runtime performance at scale, this simplicity is a real advantage.
The tradeoff is that your server does more work (rendering full HTML responses vs. JSON) and your UI is less rich than a full React application. For many use cases, that's a worthwhile tradeoff.
When to Choose HTMX
Choose HTMX when:
- You're building a form-heavy web application (CRUD, admin, data entry)
- Your team is stronger in server-side languages than JavaScript frontend
- You want minimal JavaScript complexity
- You're starting a new project that doesn't need the richness of a full SPA
- You're working with a server-side framework (Django, Rails, Laravel) that already handles templating
Skip HTMX when:
- You're building a rich interactive application (design tools, collaborative editing, complex dashboards)
- Your team is heavily invested in React
- You need offline support
- You're adding dynamic behavior to an existing SPA
Want more developer tooling insights? Subscribe to DevTools Guide — a weekly newsletter for TypeScript and JavaScript developers.