Skip to main content
株式会社オブライト
Web Development2026-08-298 min read

htmx 4.0 Released: Breaking Changes & Migration Guide

htmx 4.0 launched Aug 28, 2026 with breaking changes: explicit attribute inheritance, unified events, and fetch(). See new features and htmx 2 vs Alpine.js.


htmx 4.0 was released on August 28, 2026, the next major version of htmx. The numbering jumped straight from 2.x to 4.0, skipping htmx 3 entirely. The two biggest changes are that attribute inheritance is now explicit instead of implicit, and the internal implementation moved from XMLHttpRequest to fetch(). There is no need to migrate existing projects immediately: npm's latest tag stays on the 2.x line until early 2027, and htmx 2 will continue to be supported indefinitely. Unless you want the new features in a fresh project, existing projects do not need to rush an upgrade.

What htmx is (a quick refresher)

htmx is a library that lets you update part of a page with server-returned HTML fragments — without a full page reload — simply by adding HTML attributes such as hx-get, hx-post, and hx-target. Unlike React or Vue, it has no client-side state management of its own; instead it drives Ajax, WebSocket, and SSE-style dynamic behavior declaratively through server-side rendering plus HTML attributes. This "extend HTML as-is" philosophy is often described as a HATEOAS-style, hypermedia-driven approach. The idea of driving the UI from the server is not unique to htmx — stacks such as Hono + Inertia + React keep routing and state on the server in a similar spirit.

htmx 4.0 changes at a glance

Itemhtmx 2htmx 4
Internal transportXMLHttpRequestfetch()
Attribute inheritanceImplicit (auto-inherited by children)Explicit (requires :inherited suffix)
Event namingMixed camelCase, e.g. htmx:beforeRequestUnified htmx:phase:action[:sub-action]
XHR-specific eventsPresent (htmx:xhr:*)Removed (no longer needed with fetch())
Validation eventsPresent (htmx:validation:*)Removed (replaced by native browser validation)
History cachelocalStorage snapshotsRemoved; refetches on back navigation (restorable via hx-history-cache extension)
Morph swapSeparate extensionBundled by default
OOB swap syntaxhx-swap-oob attributeNew <hx-partial> tag added
ReactivityNone (server round-trip assumed)New hx-live (HATEOAS-oriented)
npm distribution taglatestnext (until early 2027)

Breaking change 1: explicit attribute inheritance

In htmx 2, attributes such as hx-confirm or hx-target placed on a parent element were automatically inherited by child elements unless explicitly disabled with hx-disinherit. That implicit inheritance was convenient but also a common source of unintended behavior and hard-to-trace bugs. htmx 4 removes this implicit behavior entirely: any attribute you want a child to inherit must now carry an explicit :inherited suffix.

<!-- htmx 2: hx-confirm is implicitly inherited by the child button -->
<div hx-confirm="Are you sure?">
  <button hx-delete="/item/1">Delete</button>
</div>

<!-- htmx 4: inheritance must be explicit via :inherited -->
<div hx-confirm:inherited="Are you sure?">
  <button hx-delete="/item/1">Delete</button>
</div>
A comparison showing htmx 2 cascading a parent hx-confirm to child buttons implicitly, versus htmx 4 where only attributes with the :inherited suffix cascade and a plain hx-confirm applies to the parent alone

As a result, the hx-disinherit attribute used to opt out of inheritance is no longer needed and can be removed. Places in existing templates that relied on implicit inheritance can be flagged mechanically by the migration tool described below.

Breaking change 2: unified event naming

htmx 2's event names mixed camelCase and other conventions inconsistently. htmx 4 standardizes them into a single pattern: htmx:phase:action[:sub-action]. Alongside this, XHR-specific events (htmx:xhr:*), which became unnecessary once the library moved to fetch(), and validation events (htmx:validation:*), superseded by native browser form validation, have both been removed.

htmx 2htmx 4
htmx:beforeRequesthtmx:before:request
htmx:afterRequesthtmx:after:request
htmx:beforeSwaphtmx:before:swap
htmx:afterSwaphtmx:after:swap
htmx:configRequesthtmx:config:request
htmx:xhr:* (various)Removed (unified under fetch())
htmx:validation:* (various)Removed (native validation instead)

Breaking change 3: the move to fetch() and history behavior

htmx 4 fully migrates its internal transport from XMLHttpRequest to fetch(). This change is said to be transparent for most users — visible behavior shouldn't change — but any custom code or extensions that hook into XHR-specific events will need to be rewritten. htmx 4 also drops the localStorage-based page snapshotting that htmx 2 used to speed up browser back-navigation restoration. The rationale is that third-party libraries' DOM mutations could leak into those snapshots and persist unexpectedly after restoration. In htmx 4, back navigation now refetches the <body> or the designated [hx-history-elt] element each time. If you want the old sessionStorage-style caching behavior back, you can install the hx-history-cache extension.

New features: morph swap, hx-partial, hx-live, and new extensions

- Morph swap bundled by default: an improved idiomorph algorithm is built in, so DOM-diff morphing works without installing a separate extension
- <hx-partial> tag: a custom element that expresses out-of-band (OOB) swaps and multi-element updates more clearly
- hx-live: a new HATEOAS-oriented reactivity mechanism that doesn't assume a server round-trip for every update
- New extensions: hx-preload (preloads content on mouseover), hx-download (native, fetch-based file downloads), hx-alpine-compat (smooths compatibility with Alpine.js), hx-sse (Server-Sent Events streaming), hx-ws (WebSocket streaming), hx-multipart (multipart/mixed streaming)
- htmax.js bundle: a single file that packages htmx with popular extensions

<!-- OOB swap example using hx-partial -->
<hx-partial hx-target="#messages" hx-swap="beforeend">
  <div>New message</div>
</hx-partial>

Installation and version strategy

Via CDN, 4.0 can be loaded with the following URL.

<script src="https://unpkg.com/htmx.org@4.0.0/dist/htmx.min.js"></script>

The key thing to note is that npm's latest tag stays on the 2.x line until early 2027; the 4.0 line is distributed under the next tag instead. This is deliberate: it prevents users pinning to a version-less CDN URL (or the latest npm tag) from being force-upgraded into 4.0's breaking changes without warning. If you install via npm, you need to specify the version explicitly, e.g. 4.0.0. It's also worth noting that htmx 2 will continue to be supported indefinitely, so there's no need to feel pressure to migrate quickly.

Migration steps (the shortest path)

If you're considering migrating to htmx 4, start by running the official upgrade checker against your template directory.

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

This command scans files with extensions such as .html, .php, .js, .ts, .jinja/.jinja2/.j2, .erb, and .hbs, and flags places relying on implicit attribute inheritance, renamed attributes, removed attributes, references to old event names, and use of deprecated APIs. An AI agent skill set is also provided (htmx-guidance, htmx-debugging, htmx-extension-authoring, htmx-upgrade-from-htmx2) to assist automated migration with AI coding assistants. Based on what the checker finds, the basic workflow is: add :inherited where inheritance is actually needed, rewrite event listener names, and review any code depending on the now-removed XHR-specific or validation events.

How it compares to existing tools

Itemhtmx 2htmx 4Alpine.jsHotwire TurboReact
Core philosophyHTML attribute extension + server round-tripSame, transport moved to fetch()Lightweight client-side reactivityRails-centric SPA-like behaviorClient-side virtual DOM & components
TransportXMLHttpRequestfetch()No built-in transportfetch built inArbitrary (fetch/axios, etc.)
State managementMostly server-sideMostly server-side, plus hx-liveClient-side (x-data)Mostly server-sideClient-side (useState, etc.)
DOM diffing/morphingVia a separate extensionMorph swap bundled by defaultNot addressed (manual DOM ops)Handled via Turbo StreamsVirtual DOM diffing
Learning curveLow (attribute-based)Low (attribute-based, slightly more inheritance rules)Low (lightweight, standalone use)Moderate (tied to Rails conventions)High (JSX, state management, build tooling)
Typical use caseServer-rendered appsSame, plus streaming UILight, decorative interactivity on existing pagesTurning Rails apps SPA-likeLarge, client-driven SPAs

Should you migrate? — decision criteria

For a new project, it can be worth explicitly pinning the next tag and adopting 4.0 from day one, to get the fetch()-based implementation, bundled morph swap, and the reactivity boost from hx-live. Keep in mind, though, that because it's still tagged next, further minor spec changes are possible before it stabilizes. For an existing project, the two breaking changes — explicit attribute inheritance and renamed events — touch a lot of surface area, so staying on the 2.x line (latest) is the reasonable default unless there's a specific reason to move. Since htmx 2's indefinite support has been explicitly stated, "not migrating" is a fully supported choice. If you do decide to migrate, the safe approach is to run upgrade-check first to map out the blast radius before planning the work. If you want to weigh it against a client-side routing approach, compare it with SPA-oriented options such as TanStack Router + Tailwind CSS + Vite.

Does htmx 3 exist?

No. htmx skipped version 3 entirely, moving directly from the 2.x line to 4.0.

Do I need to migrate from htmx 2 to 4.0 right away?

No. htmx 2 will continue to be supported indefinitely, and npm's latest tag stays on the 2.x line until early 2027. There's no need to rush.

How did attribute inheritance change?

In htmx 2, attributes like hx-confirm placed on a parent were implicitly inherited by child elements. In htmx 4, any attribute you want inherited must carry an explicit :inherited suffix.

Will my existing event listeners keep working?

No. Old event names like htmx:beforeRequest have been renamed to the new htmx:before:request style, and XHR-specific and validation events have been removed entirely.

Where should I start if I want to migrate?

Run npx htmx.org@4.0.0 upgrade-check -- ./templates first to detect implicit inheritance, old event names, and other affected areas before planning the migration.

Feel free to contact us

Contact Us