htmx Tutorial · Going Further · Lesson 29 of 30

Upgrading to htmx 4

What changed in htmx 4 (released August 2026): fetch, explicit inheritance, new event names, error swapping, and how to upgrade from htmx 2.

Create a free account to save this page, take notes and track your progress. Sign in

Should you upgrade now?

htmx 4.0 was released on 28 August 2026. The htmx team keeps htmx 2 supported indefinitely, and npm still installs 2.x by default (latest), with 4.x as next, until some point in early 2027. This tutorial teaches htmx 2, which is what most projects run today. For new projects either version is fine; check whether the extensions you need are ready for 4.

The biggest changes

1. Requests use fetch() instead of XMLHttpRequest. That enables streaming responses. The htmx:xhr:* progress events are gone.

2. Inheritance is explicit. In htmx 2, attributes such as hx-target and hx-confirm apply to children automatically. In htmx 4 you opt in with :inherited:

<!-- htmx 2 -->
<tbody hx-confirm="Delete this contact?" hx-target="closest tr">...</tbody>

<!-- htmx 4 -->
<tbody hx-confirm:inherited="Delete this contact?" hx-target:inherited="closest tr">...</tbody>

This is the biggest upgrade task. htmx.config.implicitInheritance = true restores the old behaviour.

3. Error responses are swapped. htmx 4 swaps every response except 204 and 304, so a 422 form with errors "just works". Use the new hx-status:422="..." attribute for per-status control.

4. Event names follow htmx:phase:action.

htmx 2 htmx 4
htmx:beforeRequest htmx:before:request
htmx:afterRequest htmx:after:request
htmx:beforeSwap / htmx:afterSwap htmx:before:swap / htmx:after:swap
htmx:configRequest htmx:config:request
htmx:load htmx:after:init
htmx:responseError htmx:response:error

5. Renamed and removed attributes. hx-disable becomes hx-ignore and hx-disabled-elt becomes hx-disable (rename in that order!). hx-vars is replaced by hx-vals (with js: values), and hx-params, hx-prompt, hx-ext and hx-history are removed.

6. Other changes: history no longer keeps page snapshots in browser storage (Back re-fetches the page); a default request timeout of 60 seconds; out-of-band swaps run after the main swap; new morph swap styles (innerMorph, outerMorph); extensions are included with a <script> tag, no hx-ext needed.

How to upgrade

  1. Read the official What's new in htmx 4 guide.
  2. Run the upgrade checker on your templates: npx [email protected] upgrade-check -- ./templates.
  3. Rename hx-disable → hx-ignore first, then hx-disabled-elt → hx-disable.
  4. Add :inherited where you relied on inheritance (or set implicitInheritance while you migrate).
  5. Rename event listeners, and review error handling now that 4xx/5xx responses swap.

Code written with explicit attributes on each element (no reliance on inheritance) and standard events is the easiest to move between versions.

Test yourself

What is the biggest upgrade task from htmx 2 to htmx 4?

  1. Marking inherited attributes with :inherited
  2. Rewriting the server in JavaScript
  3. Replacing hx-get with fetch()
  4. Adding a build step
Show answer

Answer: Marking inherited attributes with :inherited

htmx 4 makes inheritance explicit; attributes on parents no longer apply to children automatically.

Was this page helpful?