Without HTMX
-
Each interaction reloads the full page.
-
Developers must choose between full reloads or building a client app (React/Vue/etc.).
-
Ex1 :
button.addEventListener("click", async () => { const res = await fetch("/data"); document.querySelector("#result").innerHTML = await res.text(); }); -
Ex2 :
<button id="loadBtn">Load Items</button> <div id="result"></div>document.getElementById("loadBtn").addEventListener("click", async () => { const res = await fetch("/items"); // 1. Send AJAX request const html = await res.text(); // 2. Wait for server response document.getElementById("result").innerHTML = html; // 3. Update DOM });-
The code :
-
fetch-
A modern browser API to make HTTP requests (GET, POST, etc.).
-
By default, it sends a GET request to the URL.
-
Returns a Promise that resolves when the server responds.
-
awaitpauses the async function until the response arrives.
-
-
res.text()-
Reads the response body as plain text (HTML in this case).
-
Also returns a Promise, so
awaitis needed.
-
-
document.getElementById("result").innerHTML = html;-
Replaces the contents of the
#resultdiv with the HTML received. -
Only the contents of
#resultare replaced, just like in HTMX.
-
-
-
Step-by-step mechanics:
-
User clicks the button.
-
JS event listener fires.
-
JS issues a network request to
/items. -
Server responds with HTML.
-
JS inserts HTML into
#result.
-
-
Performance/Responsiveness:
-
One network round-trip per click.
-
DOM update is instant once response arrives.
-
Minimal CPU usage; modern browsers handle it efficiently.
-
Bandwidth = server response size only.
-
-
Pros:
-
Fully controlled in JS.
-
Flexible for complex logic before/after request.
-
-
Cons:
-
Boilerplate JS code for every button/form.
-
Requires attaching event listeners.
-
Harder to maintain at scale for multiple similar elements.
-
-
With HTMX
-
You keep a server-rendered architecture.
-
You get partial updates via HTML fragments instead of full reloads.
-
You avoid writing or maintaining JavaScript frameworks, build steps, or client-side state logic.
-
Ex1 :
<button hx-get="/data" hx-target="#result">Load</button> <div id="result"></div> -
Ex2 :
<button hx-get="/items" hx-target="#result">Load Items</button> <div id="result"></div>-
Step-by-step mechanics:
-
User clicks the button.
-
HTMX intercepts the click via its internal event delegation.
-
HTMX issues an AJAX GET to
/items. -
Server responds with HTML.
-
HTMX inserts the response into
#resultusinginnerHTMLby default.
-
-
Performance/Responsiveness:
-
Network round-trip identical to vanilla JS.
-
DOM update is comparable in speed.
-
Slight extra CPU overhead for HTMX event delegation (~1–2 KB script parsing, negligible for modern browsers).
-
Bandwidth identical (HTML fragment only).
-
-
Pros:
-
No JS boilerplate; behavior is entirely declarative.
-
Easily reusable: any button with
hx-*works automatically. -
Integrates cleanly with server-rendered templates.
-
Supports advanced behaviors (
hx-swap,hx-trigger,hx-vals,hx-indicator) without extra JS.
-
-
Cons:
-
Every interaction still requires a server round-trip (not instant).
-
Limited flexibility for complex logic compared to vanilla JS (requires
hx-onor external JS hooks). -
Adds a small client-side dependency.
-
-