「ReactやVueを使わずに、もっとシンプルに動的なWebアプリを作りたい…」。そう思ったことはありませんか?
2010年代後半から続くSPA(Single Page Application)全盛期に、多くの開発者は「複雑なフロントエンド」に疲れを感じ始めています。そんな中、2024〜2026年にかけて急速に注目を集めているのが、HTMXです。
HTMXは、HTMLの属性にちょっとした属性を追加するだけで、Ajax通信・CSSトランジション・WebSocketプッシュ・Server-Sent Events(SSE)を実現できるライブラリです。JavaScriptをほとんど書かずに、SPAライクなリッチなユーザー体験を構築できます。
この記事では、HTMXの基本からサーバーサイド連携、ハイパーメディアAPI設計、実践的なパターンまで、2026年最新のHTMXの世界をコード例たっぷりで解説します。
HTMXとは? なぜ2026年に注目すべきなのか
HTMXは、「HTMLをAPIとして使う」という哲学に基づいたライブラリです。Webアプリのフロントエンドで複雑な状態管理をせず、サーバーから返ってきたHTMLをそのままDOMに挿入するという、本来のWebのシンプルさに立ち返るアプローチを取ります。
HTMXの基本は、以下の3つだけです。
- hx-*属性をHTMLに追加する
- サーバーがHTMLの断片を返す
- HTMXが自動的にDOMを更新する
これだけで、クリック・フォーム送信・スクロール・タイマーなど、あらゆるイベントをトリガーにした動的なUIが実現します。
| 項目 | HTMX | React/Next.js | Alpine.js |
|---|---|---|---|
| バンドルサイズ | 〜14KB(min+gzip) | 〜100KB以上 | 〜9KB |
| 学習曲線 | 非常に緩やか(HTML知識のみ) | 急(JSX, State, Hooks...) | 緩やか |
| JavaScript記述量 | ほぼ0 | 多い | 中程度 |
| サーバーサイド | 任意の言語(HTMLを返すだけ) | Node.js必須 | 任意 |
| SEO対応 | ◎(サーバーレンダリングが標準) | ○(SSR/SSG必要) | ◯(サーバー側で完結) |
| WebSocket/SSE | 標準サポート | ライブラリ別途必要 | 別途必要 |
2026年現在、HTMXはGitHubで36,000以上のスターを獲得し、Ruby on Rails・Django・Go(Templ)・Hono.jsなど、様々なサーバーサイドフレームワークとの統合が進んでいます。個人開発者にとっては「サーバーサイドの知識だけでフロントエンドも書ける」というのが最大の魅力です。
HTMXの始め方:CDNからセットアップ
HTMXの導入は驚くほど簡単です。CDNから読み込むだけで、たった1行で始められます。
<!-- CDNで読み込み(たったこれだけ) -->
<script src="https://unpkg.com/htmx.org@2.0.4"></script>
npmでインストールする場合は以下です。
npm install htmx.org
ES Modulesとしてインポート:
import 'htmx.org';
これで準備完了。通常のHTMLファイルにhx-*属性を書き加えるだけで、動的なWebアプリが動き始めます。
基本属性:6つの属性で全てが動く
HTMXは、たった6つの基本属性で全ての動的動作を実現します。
| 属性 | 役割 | 使用例 |
|---|---|---|
hx-get |
GETリクエストを送信 | クリックでデータ読み込み |
hx-post |
POSTリクエストを送信 | フォームをAjax送信 |
hx-put |
PUTリクエストを送信 | データ更新 |
hx-delete |
DELETEリクエストを送信 | データ削除 |
hx-trigger |
トリガーをカスタマイズ | hover, ダブルクリック, ロード時 |
hx-target |
レスポンスの挿入先を指定 | 別の要素に結果を表示 |
最もシンプルな例:
<button hx-get="/api/hello" hx-target="#result">
挨拶を表示
</button>
<div id="result"></div>
クリックすると /api/hello にGETリクエストが飛び、返ってきたHTMLが #result に挿入されます。JavaScriptのイベントリスナーやfetchの記述は一切不要。これがHTMXの最大の魅力です。
実践パターン7選
ここからは、実際の開発でよく使うパターンを7つ紹介します。
1. インクリメンタルサーチ(入力即検索)
<input type="text"
name="q"
hx-get="/search"
hx-trigger="keyup changed delay:300ms"
hx-target="#search-results"
placeholder="検索...">
<div id="search-results"></div>
キー入力から300ms後に自動で検索リクエストを送信。結果をその場に表示します。hx-trigger="keyup changed delay:300ms" で「タイピングが止まったら検索」という自然なUXを実現しています。
2. 無限スクロール
<div hx-get="/posts?page=2"
hx-trigger="revealed"
hx-target="this"
hx-swap="afterend">
さらに読み込み中...
</div>
hx-trigger="revealed" は、要素が画面内に入ったときに発火します。これで無限スクロールがたった数行で実装できます。
3. フォームのAjax送信
<form hx-post="/todos"
hx-target="#todo-list"
hx-swap="beforeend">
<input type="text" name="title" required>
<button type="submit">追加</button>
</form>
<ul id="todo-list">
<li>サンプルタスク</li>
</ul>
フォーム送信をAjax化。ページ遷移なしでリストに新しいタスクが追加されます。hx-swap="beforeend" で、レスポンスのHTMLをターゲットの末尾に追加しています。
4. 削除確認とアニメーション
<button hx-delete="/todos/1"
hx-target="closest li"
hx-swap="outerHTML swap:0.5s"
hx-confirm="本当に削除しますか?">
削除
</button>
削除前に確認ダイアログを表示し、削除後は0.5秒かけてアニメーションしながら要素が消えます。hx-swap="outerHTML" で要素ごと置き換え、swap:0.5s でフェードアウトがかかります。
5. プッシュ通知(SSE)
<div hx-sse="connect:/notifications">
<div hx-get="/notifications/latest"
hx-trigger="sse:new-notification">
最新の通知を待機中...
</div>
</div>
Server-Sent Events(SSE)でサーバーからのプッシュ通知をリアルタイムに表示。WebSocketよりシンプルで、チャットや通知に向いています。
6. タブ切り替え
<div class="tabs">
<button hx-get="/tab/1"
hx-target="#tab-content"
hx-push-url="true">タブ1</button>
<button hx-get="/tab/2"
hx-target="#tab-content"
hx-push-url="true">タブ2</button>
</div>
<div id="tab-content">
デフォルトのコンテンツ
</div>
hx-push-url="true" でブラウザの履歴も更新されるので、戻るボタンでもタブ切り替えが機能します。通常のページ遷移と同じUXを提供できます。
7. 遅延読み込み(Lazy Loading)
<div hx-get="/heavy-content"
hx-trigger="load">
<img class="htmx-indicator"
src="/spinner.gif"
alt="Loading...">
</div>
ページ読み込み後に非同期で重いコンテンツを取得。htmx-indicator クラスを付けた要素は、リクエスト中のみ自動で表示されます。
サーバーサイド連携:Go + HTMXで作る本格的なWebアプリ
HTMXの真価は、サーバーサイドとの組み合わせで発揮されます。ここでは、Go言語 + Templ(テンプレートエンジン)との連携例を紹介します。
// main.go
package main
import (
"net/http"
"github.com/a-h/templ"
)
func main() {
http.HandleFunc("/api/hello", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
w.Write([]byte(`<p>こんにちは、HTMX!</p>`))
})
http.Handle("/", templ.Handler(index()))
http.ListenAndServe(":8080", nil)
}
Go + HTMXの組み合わせは、たった1つのバイナリでサーバーとフロントエンドが完結するため、個人開発のミニSaaSに最適です。Goの高速なビルドとHTMXのシンプルさが融合し、驚くほど少ないコードで動くプロダクトが完成します。
他にも以下のサーバーサイドとの組み合わせが人気です。
- Python + Django + django-htmx — Pythonistaの定番コンビ
- Ruby + Rails + turbo-rails — Hotwireとの親和性も高い
- Hono.js + Cloudflare Workers — エッジで動くHTMX
- Node.js + Express + htmx-go — 最もシンプルな構成
ハイパーメディアAPI設計:HTMLをAPIとして使う発想
HTMXを使う上で最も重要なのは、「APIはJSONではなくHTMLを返す」という発想の転換です。
従来のSPA開発では、フロントエンドがJSONを受け取り、それをJavaScriptでDOMに変換していました。HTMXでは、サーバーが既にレンダリング済みのHTML断片を返します。
// 従来のJSON API
GET /api/todos
→ [{ "id": 1, "title": "タスク" }]
// フロントエンドでJSON→DOM変換が必要
// HTMXのハイパーメディアAPI
GET /api/todos
→ <li>タスク 1</li><li>タスク 2</li>
// そのままDOMに挿入!
このアプローチのメリットは、以下の通りです。
- 状態管理が不要 — サーバーが唯一の真実(SSOT)
- バリデーションがサーバー側で完結 — 二重実装不要
- APIの変更がHTMLの変更だけ — バージョニング不要
- SEOがデフォルトで最適 — サーバーレンダリングが標準
これは、RESTの本来の原則である「ハイパーメディアとしてのアプリケーション状態エンジン(HATEOAS)」に立ち返るアプローチです。JSON APIが「データの転送」に特化しているのに対し、HTMXのハイパーメディアAPIは「UIの転送」を直接行います。
HTMX + Alpine.js:ハイブリッド構成のススメ
HTMXは「サーバーサイドで完結するUI操作」に特化していますが、クライアントサイドでの細かいインタラクション(ドロップダウンの開閉、モーダルの表示、ダークモード切り替えなど)にはAlpine.jsを組み合わせるのが定番パターンです。
<!-- Alpine.jsでクライアントサイドの状態管理 -->
<div x-data="{ open: false }">
<button @click="open = !open">
メニューを開く
</button>
<div x-show="open">
<!-- HTMXでサーバーからデータを取得 -->
<div hx-get="/api/menu-items"
hx-trigger="load"
hx-target="this">
</div>
</div>
</div>
この組み合わせのGoldilocks(最適)構成は、以下の通りです。
| レイヤー | ツール | 役割 |
|---|---|---|
| サーバーサイド | Go / Django / Hono / Rails | ビジネスロジック + HTMLレンダリング |
| サーバー→クライアント通信 | HTMX | 動的コンテンツの取得・更新 |
| クライアントインタラクション | Alpine.js(〜9KB) | ドロップダウン・モーダル・アニメーション |
| スタイル | Tailwind CSS / プレーンCSS | 見た目 |
この構成の合計バンドルサイズは HTMX(14KB)+ Alpine.js(9KB)+ Tailwind CSS(CDN最適化版) で、Reactのバンドルサイズの1/3以下です。しかも動的コンテンツは全てサーバーレンダリングされるため、初回表示速度も圧倒的に速いというメリットがあります。
HTMX + Cloudflare Workersでエッジにデプロイ
HTMXアプリは、サーバーレス環境との相性が抜群です。特にCloudflare Workersとの組み合わせは、エッジで動く超高速なHTMXアプリを実現します。
// Hono.js + Cloudflare Workers + HTMX
import { Hono } from 'hono'
const app = new Hono()
// タスク一覧(HTML断片を返す)
app.get('/todos', async (c) => {
const todos = await c.env.DB.prepare(
"SELECT * FROM todos ORDER BY id DESC"
).all()
return c.html(`
<ul hx-confirm="本当に削除しますか?">
${todos.results.map(todo => `
<li>
${todo.title}
<button hx-delete="/todos/${todo.id}"
hx-target="closest li"
hx-swap="outerHTML swap:0.3s">
🗑️
</button>
</li>
`).join('')}
</ul>
`)
})
// タスク追加
app.post('/todos', async (c) => {
const { title } = await c.req.parseBody()
await c.env.DB.prepare(
"INSERT INTO todos (title) VALUES (?)"
).bind(title).run()
// 追加したタスクのHTML断片だけを返す
return c.html(`<li>${title}</li>`, 201)
})
export default app
このコードは、Cloudflare Workers + D1データベースで動作するシンプルなTODOアプリです。ページ全体のリロードなしで追加・削除が行え、しかもグローバルエッジで動作するため、世界中どこからでも高速に応答します。
Cloudflare Workersの無料枠は 1日10万リクエストまで無料。HTMXアプリは軽量なHTML断片のやり取りが中心なので、JSON APIと比べてもトラフィック効率が良く、無料枠内で十分運用できます。
HTMXにおける注意点とベストプラクティス
HTMXは強力なツールですが、向き不向きもあります。個人開発で使う際の注意点をまとめました。
HTXMが得意なこと
- ✅ サーバーサイドレンダリングがメインのCRUDアプリ
- ✅ 管理画面・ダッシュボード
- ✅ フォームの部分送信・バリデーション
- ✅ リアルタイム通知(SSE)
- ✅ 検索・フィルター・ソートなどの一覧操作
- ✅ 静的サイトに動的要素を追加
HTMXが苦手なこと
- ❌ 複雑なクライアント状態管理(ゲーム、キャンバス操作)
- ❌ オフラインファーストのアプリケーション
- ❌ リアルタイム共同編集(WebSocketでも可能だが複雑)
- ❌ ネイティブアプリのような高頻度のUI更新
ベストプラクティス
- progressive enhancement(プログレッシブエンハンスメント)を意識する — HTMXが読み込まれなくても基本機能が動作するように、通常のフォーム送信も併用する
- hx-boostでページ全体をSPA化 — 通常のリンクやフォームに
hx-boost="true"を付けると、ページ全体のナビゲーションがAjax化される - サーバー側のバリデーションを徹底 — クライアント側のバリデーションに頼らず、サーバーでHTMLエラーメッセージを返す
- HTMXの拡張機能(Extension)を活用 —
hx-ext属性でJSONエンコード/debug/レスポンスターゲット拡張などを追加できる - 適切な入れ替え戦略(hx-swap)を選ぶ — innerHTML(デフォルト)/ outerHTML / beforebegin / afterbegin / beforeend / afterend / delete / none から最適なものを選択
まとめ:HTMXは個人開発者の新たな選択肢
HTMXは、「シンプルさに立ち返る」というWeb開発の原点回帰を体現したライブラリです。ReactやVueなどの大規模フレームワークに疲れた個人開発者にとって、HTMXは「サーバーサイドの知識をそのままフロントエンドに活かせる」という新しい可能性を開いてくれます。
特に以下のような方には、HTMXを強くおすすめします。
- バックエンドエンジニアで、フロントエンドの学習コストを減らしたい
- 「小さく始めて大きく育てる」ミニSaaSを作りたい
- バンドルサイズとパフォーマンスにこだわりたい
- JavaScriptのフレームワーク疲れを感じている
- GoやPythonなど、Node.js以外のバックエンド言語を使いたい
まずは公式サイトの HTMX Examples を眺めてみてください。15分もあれば「こんなに簡単に動くのか」と驚くはずです。そして、あなたの次のプロジェクトで、HTMXを試してみてください。
シンプルさは、最高のパフォーマンスです。