htmx 4.0 リリース解説 — 破壊的変更と移行手順を最速チェック
htmx 4.0が2026年8月28日にリリースされた。属性継承の明示化・イベント名統一・fetch()化という3つの破壊的変更に加え、morph swap標準搭載やhx-liveなどの新機能、npmのタグ方針、移行手順、そしてAlpine.jsやTurbo・Reactとの違いまでを整理して解説する。
htmx 4.0は2026年8月28日にリリースされた、htmxのメジャーバージョンである。htmx 3を飛ばして2.xから一気に4.0へ番号が進んだ。最大の変更点は「属性の継承が暗黙から明示に変わった」ことと「内部実装がXMLHttpRequestからfetch()に移行した」ことの2点で、既存プロジェクトを4.0へ即座に移行する必要はない。npmのlatestタグは2027年初頭まで2.x系のままに据え置かれ、htmx 2は無期限にサポートが継続される。新規プロジェクトで最新機能を試したい場合を除き、既存プロジェクトは慌てて移行しなくてよい。
htmxとは(おさらい)
htmxはHTML属性(hx-get、hx-post、hx-targetなど)を追加するだけで、ページ全体をリロードせずにサーバーから返されるHTML断片で画面の一部を更新できるライブラリである。ReactやVueのようなクライアントサイドの状態管理を持たず、サーバーサイドレンダリングとHTML属性ベースの宣言的な記法でAjax・WebSocket・SSEといった動的な挙動を実現するのが特徴で、「HTMLをそのまま拡張する」思想からHTMX over the wire(HATEOAS)的なアプローチとして知られる。なお、サーバー駆動でUIを組み立てるという発想は htmx に限ったものではなく、Hono + Inertia + React で作る次世代フルスタックのようにサーバー側でルーティングと状態を持つ構成でも共有されている考え方である。
htmx 4.0の変更点サマリ
| 項目 | htmx 2 | htmx 4 |
|---|---|---|
| 内部通信 | XMLHttpRequest | fetch() |
| 属性の継承 | 暗黙(子要素へ自動継承) | 明示(:inheritedサフィックス必須) |
| イベント名 | htmx:beforeRequestのようなキャメルケース混在 | htmx:phase:action[:sub-action]に統一 |
| XHR固有イベント | あり(htmx:xhr:*) | 廃止(fetch()化により不要) |
| バリデーションイベント | あり(htmx:validation:*) | 廃止(ネイティブ検証に一本化) |
| 履歴キャッシュ | localStorageにスナップショット保存 | 廃止、戻る操作で再フェッチ(hx-history-cache拡張で復活可) |
| morph swap | 拡張機能として別途導入 | 標準同梱 |
| OOB swapの記法 | hx-swap-oob属性 | <hx-partial>タグを追加 |
| リアクティビティ | なし(サーバー往復が前提) | hx-live(HATEOAS志向)を新設 |
| npm配布タグ | latest | next(2027年初頭まで) |
破壊的変更(1): 属性継承の明示化
htmx 2では、親要素に付けたhx-confirmやhx-targetなどの属性は、明示的に無効化(hx-disinherit)しない限り子要素に自動で継承されていた。この暗黙の継承は便利な反面、意図しない挙動やデバッグの難しさの原因になっていた。htmx 4ではこの仕様が撤廃され、継承させたい属性には:inheritedサフィックスを明示的に付ける必要がある。
<!-- htmx 2: hx-confirm は子のボタンへ暗黙的に継承される -->
<div hx-confirm="Are you sure?">
<button hx-delete="/item/1">Delete</button>
</div>
<!-- htmx 4: 継承させたい属性には :inherited を明示する -->
<div hx-confirm:inherited="Are you sure?">
<button hx-delete="/item/1">Delete</button>
</div>
この変更に伴い、継承を止めるためのhx-disinherit属性はもはや不要になり、削除してよいとされている。既存テンプレートで暗黙の継承に依存している箇所は、後述する移行ツールで機械的に検出できる。
破壊的変更(2): イベント名の統一
htmx 2のイベント名はキャメルケースを含む命名が混在していたが、htmx 4ではhtmx:phase:action[:sub-action]という統一パターンに整理された。あわせて、fetch()化によって不要になったXHR固有イベント(htmx:xhr:*)と、ネイティブのフォームバリデーションに一本化されたことで不要になったバリデーションイベント(htmx:validation:*)が廃止されている。
| htmx 2 | htmx 4 |
|---|---|
htmx:beforeRequest | htmx:before:request |
htmx:afterRequest | htmx:after:request |
htmx:beforeSwap | htmx:before:swap |
htmx:afterSwap | htmx:after:swap |
htmx:configRequest | htmx:config:request |
htmx:xhr:*(各種) | 廃止(fetch()に統一) |
htmx:validation:*(各種) | 廃止(ネイティブ検証へ) |
破壊的変更(3): fetch()化と履歴(history)の挙動変更
htmx 4は内部通信をXMLHttpRequestからfetch()へ全面的に移行した。多くのユーザーにとってはこの変更は透過的(見た目上の挙動は変わらない)とされているが、XHR固有のイベントに依存したカスタムコードや拡張機能は書き換えが必要になる。あわせて、htmx 2で行っていたlocalStorageへのページスナップショット保存によるブラウザ「戻る」操作の高速復元も廃止された。これは、サードパーティのライブラリによるDOM操作がスナップショットに残り、復元時に意図しない状態になり得るという問題への対応である。htmx 4では戻る操作のたびに<body>または[hx-history-elt]要素を再フェッチする。従来のsessionStorageベースのキャッシュ挙動を復活させたい場合は、hx-history-cache拡張を導入すればよい。
新機能: morph swap / hx-partial / hx-live / 新拡張
- morph swapの標準同梱: 改良版idiomorphアルゴリズムを内蔵し、拡張機能を別途入れなくてもDOM差分更新(モーフィング)が使える
- <hx-partial>タグ: Out-of-Band(OOB)swapや複数要素の同時更新をより明快な記法で書けるカスタム要素
- hx-live: サーバー往復を前提としないHATEOAS志向のリアクティビティ機構
- 新拡張群: hx-preload(マウスオーバーで先読み)、hx-download(fetchベースのネイティブファイルダウンロード)、hx-alpine-compat(Alpine.jsとの互換性向上)、hx-sse(Server-Sent Eventsストリーミング)、hx-ws(WebSocket)、hx-multipart(multipart/mixedストリーミング)
- htmax.jsバンドル: 主要な拡張機能をまとめた単一ファイル配布
<!-- hx-partial による OOB swap の例 -->
<hx-partial hx-target="#messages" hx-swap="beforeend">
<div>New message</div>
</hx-partial>インストールとバージョン方針
CDN経由では以下のURLで4.0を読み込める。
<script src="https://unpkg.com/htmx.org@4.0.0/dist/htmx.min.js"></script>重要なのは、npmのlatestタグは2027年初頭まで2.x系のままに据え置かれることである。4.0系はnextタグで配布される。これは、バージョン指定なしのCDN URL(例: htmx.org/dist/htmx.min.jsのような最新版参照)を使っている既存ユーザーが、意図せず4.0へ強制アップグレードされて破壊的変更の影響を受けることを防ぐための措置である。npmでインストールする場合は4.0.0のようにバージョンを明示指定する必要がある。また、htmx 2は今後も無期限にサポートが継続される方針が明言されており、移行を急ぐ必要はない。
移行手順(最短ルート)
htmx 4への移行を検討する場合、まず公式が提供するアップグレードチェッカーをテンプレートディレクトリに対して実行する。
npx htmx.org@4.0.0 upgrade-check -- ./templatesこのコマンドは.html、.php、.js、.ts、.jinja/.jinja2/.j2、.erb、.hbsといった拡張子のファイルを走査し、暗黙の属性継承に依存している箇所、リネームされた属性、廃止された属性、旧イベント名の参照、非推奨APIの利用を検出してくれる。あわせて、LLM向けのエージェントスキル(htmx-guidance、htmx-debugging、htmx-extension-authoring、htmx-upgrade-from-htmx2)も提供されており、AIコーディングアシスタントを使った自動移行の補助に利用できる。検出結果をもとに、属性への:inherited付与、イベントリスナー名の書き換え、XHR固有イベントやバリデーションイベントに依存したコードの見直しを行うのが基本の流れである。
既存ツールとの違い
| 項目 | htmx 2 | htmx 4 | Alpine.js | Hotwire Turbo | React |
|---|---|---|---|---|---|
| 基本思想 | HTML属性拡張+サーバー往復 | HTML属性拡張+サーバー往復(fetch()化) | 軽量なクライアント側リアクティビティ | Railsを軸としたSPA的挙動の付与 | クライアント側の仮想DOM・コンポーネント |
| 通信方式 | XMLHttpRequest | fetch() | 通信機構は持たない | fetch内蔵 | 任意(fetch/axios等) |
| 状態管理 | 基本的にサーバー側 | 基本的にサーバー側+hx-live | クライアント側(x-data) | サーバー側中心 | クライアント側(useState等) |
| DOM差分更新 | 拡張機能でmorph対応 | 標準でmorph swap同梱 | 非対応(DOM操作は個別) | Turbo Streamsで対応 | 仮想DOM diff |
| 学習コスト | 低い(HTML属性ベース) | 低い(属性ベース、継承ルールがやや増加) | 低い(軽量・単体利用向き) | 中程度(Rails文化への依存) | 高い(JSX・状態管理・ビルド設定) |
| 主な用途 | サーバーサイドレンダリング中心のアプリ | 同左+ストリーミングUI | 既存ページへの軽量な装飾的インタラクション | Rails製アプリのSPA化 | 大規模なクライアント主導のSPA |
移行すべきか — 判断基準
新規プロジェクトであれば、fetch()ベースの新しい内部実装やmorph swap標準同梱、hx-liveによるリアクティビティ強化など4.0の恩恵を最初から受けられるため、nextタグを明示指定して4.0を採用する価値がある。ただしnextタグの位置づけ上、今後もマイナーな仕様変更が入る可能性がある点は踏まえておきたい。既存プロジェクトの場合は、属性継承の明示化とイベント名変更という2つの破壊的変更の影響範囲が大きいため、急ぐ理由がなければ2.x系(latest)に留まるのが妥当である。htmx 2は無期限サポートが明言されているため、「移行しない」という選択も正式にサポートされた選択肢である。移行するとしても、まずはupgrade-checkコマンドで影響範囲を洗い出してから計画を立てるのが安全だ。クライアント側でルーティングと状態を持つ構成と比較したい場合は、TanStack Router + Tailwind CSS + Vite 徹底解説のようなSPA寄りの選択肢と並べて検討するとよい。
htmx 3は存在しないのですか?
存在しません。htmxはバージョン2.xの次に3を飛ばして4.0へ番号を進めました。
今すぐhtmx 2から4.0へ移行しないと使えなくなりますか?
いいえ。htmx 2は無期限にサポートが継続される方針が明言されており、npmのlatestタグも2027年初頭まで2.x系のままです。急いで移行する必要はありません。
属性の継承はどう変わりましたか?
htmx 2では親要素の属性(例: hx-confirm)が子要素へ暗黙的に継承されていましたが、htmx 4では継承させたい属性に:inheritedサフィックスを明示的に付ける必要があります。
既存のイベントリスナーはそのまま動きますか?
動きません。htmx:beforeRequestのような旧イベント名はhtmx:before:requestのような新しい命名規則に変更され、XHR固有イベントとバリデーションイベントは廃止されています。
移行作業はどこから始めればよいですか?
npx htmx.org@4.0.0 upgrade-check -- ./templatesを実行し、暗黙の継承や旧イベント名など影響を受ける箇所を検出することから始めるのが最短ルートです。
お気軽にご相談ください
お問い合わせ