HTMX Frontend Website Development
HTMX is a library that brings AJAX, WebSocket, and Server-Sent Events back into HTML attributes. You describe behavior straight in markup, server returns HTML fragments, browser inserts them in the right place in DOM. No JavaScript needed at all.
This isn't a step back — this is a conscious choice of HATEOAS architecture (Hypermedia as the Engine of Application State), where server manages state and client only displays.
Working principle
Classic AJAX: server → JSON → client parses → updates DOM via JS.
HTMX: server → HTML fragment → HTMX inserts into target element.
<!-- Instead of fetch + JSON + DOM manipulation -->
<button
hx-post="/cart/add"
hx-vals='{"product_id": "42"}'
hx-target="#cart-count"
hx-swap="innerHTML"
>
Add to cart
</button>
<span id="cart-count">3</span>
Server on /cart/add returns just <span>4</span> — and counter updated. All JS is htmx.min.js (14 KB gzip).
Attributes and capabilities
| Attribute | What it does |
|---|---|
hx-get/post/put/delete |
HTTP request to specified URL |
hx-target |
CSS selector of target element |
hx-swap |
Swap strategy: innerHTML, outerHTML, beforeend, afterend, etc. |
hx-trigger |
Trigger event (click, input delay:300ms, revealed) |
hx-push-url |
Updates URL in address bar |
hx-select |
Selects part of response to insert |
hx-boost |
Turns all links/forms into AJAX requests |
hx-indicator |
Loading indicator element |
hx-confirm |
Confirmation dialog before request |
hx-ws |
WebSocket connection |
hx-sse |
Server-Sent Events |
Pattern: table with sorting and pagination
<!-- templates/users/table.html -->
<table id="users-table">
<thead>
<tr>
<th>
<a
hx-get="/users?sort=name&order=asc"
hx-target="#users-table"
hx-push-url="true"
>Name ↕</a>
</th>
<th>Email</th>
<th>Role</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user.name }}</td>
<td>{{ user.email }}</td>
<td>{{ user.role }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div
hx-get="/users?page={{ next_page }}"
hx-target="#users-table tbody"
hx-swap="beforeend"
hx-trigger="revealed"
>
<!-- Infinite scroll: loads when element appears in viewport -->
</div>
Server handler on Laravel:
public function index(Request $request): Response
{
$users = User::query()
->when($request->sort, fn($q) => $q->orderBy($request->sort, $request->order ?? 'asc'))
->paginate(20);
// If HTMX request — return only table fragment
if ($request->header('HX-Request')) {
return response()->view('users.table', compact('users'));
}
// Regular request — full page
return response()->view('users.index', compact('users'));
}
Inline editing
<tr id="user-42">
<td>John Petrov</td>
<td>[email protected]</td>
<td>
<button
hx-get="/users/42/edit"
hx-target="#user-42"
hx-swap="outerHTML"
>Edit</button>
</td>
</tr>
Server on /users/42/edit returns <tr> with form. After save — returns updated <tr> with data. Without a single line of JavaScript.
Integration with Alpine.js
HTMX and Alpine.js combine well: HTMX manages network requests and DOM updates, Alpine.js handles local interactivity (dropdowns, tabs, form validation):
<div
x-data="{ open: false }"
hx-get="/notifications"
hx-trigger="load"
hx-target="#notifications-list"
>
<button @click="open = !open" class="relative">
Notifications
<span id="notifications-count" class="badge">0</span>
</button>
<div x-show="open" @click.outside="open = false">
<ul id="notifications-list"></ul>
</div>
</div>
WebSocket and SSE for real-time
<!-- Server-Sent Events: real-time update -->
<div hx-sse="connect:/events/prices">
<span
hx-sse="swap:price-update"
hx-target="this"
hx-swap="innerHTML"
id="btc-price"
>Loading...</span>
</div>
Server sends:
event: price-update
data: <span>$67,234</span>
Price updates without polling, without JS handlers.
Implementation timeline
- Week 1: HTMX integration into existing backend (Laravel/Django/Rails/Go), basic request/response patterns setup
- Week 2: CRUD interfaces, pagination, search, sorting
- Week 3: real-time via SSE/WebSocket, optimistic updates, loading indicators
- Week 4: testing, optimization, pattern documentation for team
For existing server applications HTMX allows adding SPA-like behavior without rewriting frontend. This is especially valuable when migrating from classic MPA to interactive UI without changing backend technology.







