Skip to content

The publication for web craftspeople Sunday, 30 August 2026

Front-end

htmx 4.0 moves to fetch() and makes attribute inheritance explicit

Released on 28 August 2026, htmx 4.0.0 rebuilds its engine around fetch() and ships deliberate breaking changes. Attribute inheritance, event naming and history handling all change, while the 2.x line stays the default install.

The htmx library shipped version 4.0.0 on 28 August 2026, after eight months of work. The deepest change is invisible to end users: the internal engine drops XMLHttpRequest in favour of fetch(). That foundation unlocks streaming of HTML fragments, but it comes with breaking changes that every 2.x project must absorb before switching.

From XMLHttpRequest to fetch(): a rewritten engine

Moving to fetch() simplifies the implementation and enables progressive rendering: fragments returned by the server can appear as they arrive, without waiting for the full response. The trade-off is clear: any extension, interceptor or library that hooked into htmx 2.x’s request layer will stop working until it is adapted to the new API.

Three behavioural breaks to plan for

The first affects attribute inheritance, now explicit. An attribute is no longer propagated to child elements by default; it must carry the :inherited suffix. The hx-disinherit attribute, which used to block that propagation, is gone because it no longer has a purpose.

<!-- htmx 2.x: inherited implicitly -->
<div hx-confirm="Are you sure?">…</div>

<!-- htmx 4.0: inheritance is declared -->
<div hx-confirm:inherited="Are you sure?">…</div>

The second concerns events, standardised on the htmx:phase:action pattern. Scripts listening for the old names have to be updated.

htmx 2.xhtmx 4.0
htmx:beforeRequesthtmx:before:request
htmx:afterRequesthtmx:after:request
htmx:beforeSwaphtmx:before:swap
htmx:configRequesthtmx:config:request
htmx:xhr:*removed
hx-varshx-vals with the js: prefix
hx-promptextension to load

The third is about history. htmx 4.0 no longer uses localStorage by default: on back navigation, the page is re-fetched from the server. Projects that relied on the local cache can restore a close behaviour through the new hx-history-cache extension, backed by sessionStorage.

The heart of htmx 4.0 is not new syntax but an engine rebuilt around fetch() that makes HTML streaming possible.

Native morphing, streaming and new extensions

htmx 4.0 brings swap morphing in without an external dependency, based on the idiomorph algorithm: a fragment replaces the target while preserving existing DOM state. A new <hx-partial> tag appears to orchestrate out-of-band style swaps more legibly. Around the engine, a family of extensions supports the transition.

Version 4.0 stays published under the npm next tag, while the 2.x line keeps latest until early 2027. Projects that load htmx from a CDN URL without a version number will therefore not be upgraded by accident.

Notable extensions include hx-preload for preloading, hx-download for file downloads, hx-sse and hx-ws for event-stream and WebSocket streaming, hx-multipart for composite responses, and hx-alpine-compat to coexist with Alpine.js. An htmax.js bundle packages htmx with a ready-made set of extensions.

Migration: tooling and timeline

A command-line checker reviews templates and flags implicit inheritance, renamed or removed attributes, old event names and deprecated APIs.

npx [email protected] upgrade-check -- ./templates

The team also ships skill files aimed at coding assistants (htmx-guidance, htmx-debugging, htmx-extension-authoring, htmx-upgrade-from-htmx2) to assist diagnosis and the migration of a 2.x codebase.

The bottom line

htmx 4.0.0 is a deliberate breaking release: the engine moves to fetch(), inheritance becomes explicit, events are renamed and history stops relying on localStorage. Nothing forces an immediate migration, since 2.x remains the default install, but teams aiming for fragment streaming now have a mapped path, verification tooling included.

I have shipped htmx to production on several client projects, and the :inherited suffix is the kind of break I welcome: implicit inheritance in 2.x was a source of hard-to-trace surprises. My advice is still not to rush. As long as 2.x holds the latest tag, it is better to run upgrade-check on a dedicated branch, gauge the size of the job, and migrate when streaming brings a real gain rather than out of reflex for novelty. — Simon Janvier

Further reading

Official announcement and release notes: htmx 4.0.0 has been released.

Also on Mail Studio

Read next