Skip to content

htmx 4.0 Released: fetch() Replaces XHR, Morph Swaps Built In

Karify98 & Amy ๐ŸŒธยท
Cover Image for htmx 4.0 Released: fetch() Replaces XHR, Morph Swaps Built In

htmx 4.0.0 shipped on August 28, capping eight months of work. The release swaps the engine from XMLHttpRequest to fetch(), brings morph swaps and the <hx-partial> tag into the core โ€” but the most telling detail is how htmx chose not to force anyone to upgrade.

For context, htmx is the small library that lets you attach HTML attributes (hx-get, hx-post, hx-swap...) so the server returns HTML fragments and the page updates in place. No build step, no client-side state, no SPA framework. This is the first major release after a long stable run on the 2.x line.

Three breaking changes โ€” and a new engine underneath

From a user's perspective, 4.0 is almost identical to 2.x. The differences come down to three design decisions, plus one large internal change.

The biggest change is that attribute inheritance is now explicit. Previously, attributes on a parent element applied to children automatically โ€” convenient but confusing, like CSS. Now inheritance requires the :inherited suffix:

<!-- htmx 2 -->
<div hx-confirm="Are you sure?">
  <button hx-delete="/item/1">Delete</button>
</div>

<!-- htmx 4 -->
<div hx-confirm:inherited="Are you sure?">
  <button hx-delete="/item/1">Delete</button>
</div>

This is the largest upgrade burden, but the behavior becomes predictable. Attributes like hx-disinherit are no longer needed and should be removed.

Second, event names are standardized. The old event system grew organically and was hard to reason about. Every event now follows htmx:phase:action[:sub-action] โ€” htmx:before:request, htmx:after:swap, and so on. The xhr:* events are gone (htmx uses fetch now), and validation:* is removed in favor of native browser form validation.

Third, history no longer uses localStorage by default. The 2.x line cached page snapshots in localStorage to restore them on back navigation, but those snapshots could carry DOM mutations from third-party libraries โ€” the elements came back while the JavaScript logic did not. Version 4.0 re-fetches the page and swaps it into <body> on back navigation, which is cleaner and, with good request caching, just as fast.

Underneath, the whole engine moved from XMLHttpRequest to fetch(). For most users this is invisible โ€” but it is exactly what unlocks the new features below.

Two new features: morph swaps and hx-partial

Morph swaps are now built in. Instead of replacing an element wholesale, htmx diffs the old and new DOM and patches only what changed โ€” smoother for stateful elements like an input mid-typing, a playing video, or a focused field. This was the job of idiomorph, now integrated and improved directly.

<hx-partial> is a new tag that makes out-of-band swaps clearer. Instead of nested syntax to update multiple regions at once, you wrap each fragment in its own tag:

<hx-partial hx-target="#messages" hx-swap="beforeend">
  <div>New message</div>
</hx-partial>
<hx-partial hx-target="#count">
  <span>5</span>
</hx-partial>

Both features push toward the same goal: making hypermedia smooth enough that you no longer reach for an SPA just to get a responsive feel.

A new extension ecosystem โ€” and its own scripting solution

Much of the energy in 4.0 lives in the extensions. Moving to fetch() let the team rethink how extensions work, producing a batch of new or rewritten ones: hx-preload (preload content on hover), hx-download (fetch-based file downloads), and hx-alpine-compat plus hx-history-cache for Alpine.js compatibility.

The standout is a trio of streaming HTML extensions: hx-sse (Server-Sent Events), hx-ws (WebSocket), and hx-multipart (multipart/mixed). They let the server push HTML fragments to the client in real time โ€” real-time without a separate client library.

Finally, the team introduced hx-live, a small frontend scripting solution inspired by Alpine.js, jQuery, and hyperscript. Alongside it, the htmax.js bundle ships htmx with the most popular extensions in a single file for those who don't want to pick and choose.

Upgrading: a CLI tool, LLM skills, and no forced migration

The team ships a command-line tool to find what needs changing:

npx htmx.org@4.0.0 upgrade-check -- ./templates

It scans templates and flags each spot needing :inherited, an old event name, or a removed attribute. There are also four skills files for LLMs (guidance, debugging, extension-authoring, upgrade) โ€” a notable move as more developers lean on AI coding assistants to write and fix code.

The subtlest part of this release is the versioning policy. htmx does not mark 4.0 as latest on NPM: the 2.x line keeps that tag, while 4.0 holds next until early 2027. The stated reason is simple โ€” they don't want to silently push people on non-versioned CDN URLs onto a release with breaking changes. htmx 2 will be supported indefinitely.

What this means for developers

  • On htmx 2: no rush to upgrade, but if you do, run upgrade-check first. The main burden is adding :inherited to attributes that once relied on implicit inheritance.
  • Tired of SPAs: htmx 4 plus morph swaps and hx-live can now cover much of what used to require a framework. It's a reasonable moment to try hypermedia on a small project.
  • Needing real-time: streaming HTML via hx-sse/hx-ws lets the server push updates without a complex WebSocket client.
  • Using AI coding assistants: official skills files help models generate correct 4.0 code instead of outdated htmx 2 patterns.

The key thing to understand about htmx is that it's a long-term bet on hypermedia and server-side rendering, against the JavaScript framework churn. Version 4.0 doesn't add flashy features โ€” it reinforces the foundation so that bet holds for years to come.

What to know

  • htmx 4.0.0 shipped August 28, 2026 after eight months of work; the engine moved from XMLHttpRequest to fetch().
  • Three breaking changes: explicit attribute inheritance (:inherited), standardized event names, and history dropping localStorage.
  • Two new core features: morph swaps (idiomorph) and the <hx-partial> tag.
  • New extensions include streaming HTML (hx-sse, hx-ws, hx-multipart) and the hx-live scripting solution.
  • htmx 2 remains latest on NPM; 4.0 stays next until early 2027 โ€” nobody is forced to upgrade.

A major release is rarely this quiet, and the quiet is the statement. htmx 4.0 isn't trying to grab attention โ€” it's building to last, in line with the "100-year web services" philosophy the team has pursued all along.


Content assisted by AI (Amy ๐ŸŒธ). Reviewed by the author.

Related Posts