HTMX は『SPA への反動』として支持されるアプローチ
HTMX は、HTML の属性だけで画面の一部を書き換える軽いライブラリです。サーバーが返す HTML の断片をそのまま差し込むので、SPA のようにクライアント側で状態を組み立てる仕組みを持たずに、動きのある画面を作れます。本記事では、htmx の公式サイトとドキュメント(2026年10月21日に確認)をもとに、使い方と向き不向き、本番で気をつける点を整理します。
HTMX の特徴
(1) HTML 属性で動的化:hx-get/hx-post 等。(2) サーバーが HTML 部分を返す:JSON ではない。(3) 軽量:公式サイトによると圧縮後およそ16KB で、ほかのライブラリに依存しない。(4) JS フレームワーク不要:素のHTML+ 属性。(5) Progressive Enhancement:hx-boost を使ったリンクやフォームは、JavaScript が無効でも通常のリンク・フォームとして動く。最新は 2.x 系で、IE11 に対応する 1.x 系もサポートが続いています。
適用するべきプロジェクト
(1) サーバーレンダリング中心:Rails/Django/Phoenix。(2) 小〜中規模アプリ。(3) SEO 重視:サーバーが完成した HTML を返す。(4) シンプルなインタラクション:検索候補・無限スクロール・フォームの一部更新など。(5) JS 依存を避けたい。逆に、オフラインで動かす、画面の状態が複雑に絡み合う、といった SPA 向きの要件には不向きです。クライアント側の描画を軽く保つ別の選択肢としては、SolidJS 実践 も参考になります。
基本的な使い方
(1) hx-get/hx-post:HTTP リクエストを出す。(2) hx-target:レスポンスを入れる場所を CSS セレクタで指定。(3) hx-swap:差し込み方。(4) hx-trigger:発火のタイミング。(5) hx-indicator:読み込み中の表示。
| 属性 | 主な値(公式ドキュメント) |
|---|---|
| hx-swap | innerHTML(既定・要素の中身を置き換え)、outerHTML(要素ごと置き換え)、beforebegin・afterbegin・beforeend・afterend(前後に追加)、delete(要素を消す)、none(差し込まない) |
| hx-trigger | click などのイベントのほか、load(読み込み時に1回)、revealed(画面に入ったとき1回)、intersect(交差したとき1回)、every 2s(2秒ごとのポーリング) |
| レスポンスの扱い | 204 は何もしない。2xx・3xx は差し込む。4xx・5xx は差し込まずエラー(htmx:responseError イベント)。ポーリングは 286 を返すと止まる |
※htmx 公式ドキュメント(2026年10月21日に確認)。レスポンスの扱いは htmx.config.responseHandling で変えられます。
公式ドキュメントの「Active Search」の例では、検索欄に hx-trigger="keyup changed delay:500ms" を付けています。changed は値が変わったときだけ、delay:500ms はキー入力から500ミリ秒待ってからリクエストを出す、という意味で、1文字打つたびにサーバーへ問い合わせが飛ぶのを防げます。似た修飾子に、一定の時間に1回までに絞る throttle や、1回だけ動かす once もあります。読み込み中の表示は、リクエスト中の要素に付く htmx-request クラスと htmx-indicator クラスの組み合わせで出せます。
サーバー側の実装
(1) HTML 部分を返す:JSON でなく。(2) テンプレートエンジン:Jinja/ERB/EJS 等。(3) HX-Request ヘッダーで分岐:htmx からのリクエストには HX-Request ヘッダーが付くので、通常のアクセスにはページ全体、htmx からのアクセスには断片を返す、と出し分けられます。(4) API は不要のケースも。(5) SSR と相性良い。JavaScript が無効な環境まで考える場合、公式ドキュメントは、hx-boost 以外のパターンでは手間が増え、一部の機能はあきらめる必要があると書いています。
Alpine.js との組合せ
(1) Alpine.js:クライアント側の小さな状態管理。(2) HTMX + Alpine:サーバーとのやり取りは HTMX、開閉やタブの切り替えのような画面内だけの動きは Alpine、と役割を分けて使う。(3) 軽量UI の組み合わせとして一式で使える。(4) 覚える API が少ない:どちらも HTML の属性が中心。(5) ビルド工程なしで始められる構成も取れる。
本番運用の現実
(1) セキュリティ:HTMX は HTML の表現力を上げるため、悪意のある HTML を差し込まれたときの影響も大きくなります。公式ドキュメントの第一のルールは「ユーザーが入力した内容はすべてエスケープする」です。(2) 同一ドメインの制限:htmx.config.selfRequestsOnly は既定で true で、今いるページと同じドメインにしかリクエストを出しません。(3) 外部の HTML を含む場所には hx-disable を付けて、HTMX の属性を処理させない。(4) CSRF 対策:hx-headers でトークンを毎回のリクエストに付けられる。(5) 履歴のキャッシュ:htmx.config.historyCacheSize は既定で10で、ブラウザの localStorage にページの HTML が残ります。個人情報を扱う画面なら0にする設定も用意されています。さらに Content Security Policy で、ほかのドメインへの通信やインラインのスクリプトを止める多層の守りを公式は勧めています。
失敗しがちなパターン
(1) SPA 級の要件に適用:限界突破。(2) サーバー負荷増:毎回 HTML を組み立てるぶん、JSON より重いことも。(3) 状態管理の複雑化。(4) エスケープ漏れ:ユーザーの入力をそのまま断片に入れる。(5) キャッシュ困難:断片ごとに内容が異なる。対策は、(1)用途確認、(2)CDN 活用、(3)Alpine併用、(4)テンプレートの自動エスケープと hx-disable、(5)Edge cache、です。
この記事のデータの出典
- htmx 公式サイト(htmx.org)とドキュメント(Docs)(2026年10月21日に確認)

