📋 目錄
2025 年 HTMX 2.0 正式發布,標誌著一個重要的訊號:瀏覽器放棄 IE 以後,終於有一個庫可以徹底擁抱這個事實——不需要支援任何舊瀏覽器,HTML 屬性驅動的互動可以做到多麼徹底。本文整理 HTMX 2.0 的新特性、它的核心哲學、以及什麼樣的專案適合採用 HTMX。
為什麼前端工程師要關心 HTMX
大多數前端工程師對 HTMX 的第一印象是「奇怪的玩具」:用 HTML 屬性來發 AJAX 請求,用 hx-get、hx-post 取代 fetch 和 axios。這看起來像是在走回頭路。
但 HTMX 的實際使用者已經用這種方式建構了大量生產應用,從內部工具到電子商務平台都有。HTMX 的核心論點是:多數網頁應用的互動,並不需要 SPA 的複雜度。
這個論點在 2026 年變得越來越有力。React 的 Virtual DOM、Redux、Router——這些加起來讓你的 bundle 增加 200KB,而 HTMX 整個庫只有約 14KB(gzipped)。如果你做的是 CRUD 應用、內部工具、或內容網站,這個差距有意義。
HTMX 2.0 是這個方向的成熟化信號:不再需要 IE、Extensions 模組化、Web Component 支援提升。如果你曾經對 HTMX 感興趣但覺得「還不夠成熟」,現在是重新評估的時機。
HTMX 的核心哲學:HTML 屬性驅動的互動
HTMX 的設計理念:互動應該用 HTML 屬性宣告,而不是 JavaScript。
<!-- 點擊按鈕,發 GET 請求到 /news,結果放到 #news-list 這個元素裡 -->
<div id="news-list">
<!-- 初始內容 -->
</div>
<button hx-get="/news"
hx-target="#news-list"
hx-swap="innerHTML">
載入最新消息
</button>
<!-- 表單提交,自動處理 JSON 格式 -->
<form hx-post="/api/submit"
hx-target="#result"
hx-swap="innerHTML">
<input name="email" type="email" required />
<button type="submit">送出</button>
</form>
<div id="result"></div>
對比傳統 JavaScript 寫法:
// 傳統 fetch 寫法
const btn = document.querySelector('.load-news');
const list = document.getElementById('news-list');
btn.addEventListener('click', async () => {
const res = await fetch('/news');
const html = await res.text();
list.innerHTML = html;
});
HTMX 把這個邏輯濃縮成三個屬性:hx-get(用什麼方法)、hx-target(結果放到哪)、hx-swap(怎麼置換)。前端 JavaScript 程式碼,從 10 行變成 3 個屬性。
HTMX 2.0 的主要新特性
1. 移除 IE 支援:終於可以不用再假裝 IE 還活著
HTMX 2.0 最大的變化不是新功能,而是不再需要支援 Internet Explorer。這讓 HTMX 可以使用:
- 現代瀏覽器的原生 fetch API
- ES6+ 的語法
- 更好的瀏覽器內建事件處理
<!-- HTMX 2.0:利用瀏覽器原生能力 -->
<button hx-get="/data"
hx-swap="innerHTML"
hx-trigger="revealed">
當元素進入視口時自動載入
</button>
hx-trigger="revealed" 依賴瀏覽器的 IntersectionObserver,在 HTMX 1.x 需要自己 polyfill,HTMX 2.0 假設瀏覽器有這能力。
2. Web Component 支援改善
HTMX 2.0 增強了對 Shadow DOM 和 Custom Elements 的支援。這是 HTMX 過去最被抱怨的痛點之一。
使用 Shadow DOM
// 將 HTMX 加入 Shadow DOM
class MyElement extends HTMLElement {
connectedCallback() {
// HTMX 現在正確處理 shadow roots
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<button hx-get="/news" hx-target="#content" hx-swap="innerHTML">
載入新聞
</button>
<div id="content"></div>
`;
// 初始化這個 shadow root 內的 HTMX
htmx.process(this.shadowRoot);
}
}
與 Custom Elements 互動
<!-- HTMX 2.0 支援與 custom elements 的屬性互動 -->
<my-card hx-get="/card-content"
hx-trigger="click"
hx-target="this">
點擊載入內容
</my-card>
3. Extensions 移出核心,各自獨立版本控制
HTMX 1.x 將 SSE(Server-Sent Events)、WebSocket、AJA 等功能放在核心庫裡。HTMX 2.0 將這些 Extensions 移出,各自獨立維護:
| Extension | 說明 | 獨立版本 |
|---|---|---|
| htmx-ext-sse | Server-Sent Events | 單獨 npm/下載 |
| htmx-ext-ws | WebSocket | 單獨 npm/下載 |
| htmx-ext Ajax | 增強 AJAX | 單獨 npm/下載 |
| htmx-ext preload | 預先載入連結目標 | 單獨 npm/下載 |
<!-- HTMX 2.0:需要哪個 extension,再单独引入 -->
<script src="htmx.min.js"></script>
<script src="htmx-ext-sse.min.js"></script>
<!-- 使用 SSE: -->
<div hx-sse="connect /events">
<div hx-sse="swap:message">
<!-- 伺服器推送的訊息會出現在這裡 -->
</div>
</div>
好處:
- 主庫更小(如果不用 SSE/WSS)
- 各 extension 可以有自己的發布節奏
- 升級一個 extension 不影響主庫穩定性
4. API 穩定性承諾
HTMX 2.0 官方承諾:「Unless there are specific bugs to fix, there’s no reason to upgrade」(除非有特定 bug 要修,不然沒有理由升級)。
這個承諾對採用 HTMX 的組織非常重要:HTMX 不是那種每三個月就 major version 跳一次、逼你重構的框架。
HTMX 的實際應用場景
Server-Sent Events:即時更新不需要 WebSocket
HTMX 的 SSE 整合,讓伺服器可以主動推送更新到瀏覽器,而不需要自己管理 WebSocket 連線:
<!-- 即時股價更新頁面 -->
<div hx-sse="connect /stock-stream"
hx-swap="none">
<!-- 股價每次更新,自動置換 -->
<div hx-sse="swap:price_update"
hx-swap="innerHTML"
id="price-display">
<!-- 初始或當前股價 -->
</div>
<!-- 交易量 -->
<div hx-sse="swap:volume_update"
hx-swap="innerHTML"
id="volume-display">
</div>
</div>
伺服器端(Python/Flask):
from flask import Flask, Response, stream_with_context
app = Flask(__name__)
@app.route('/stock-stream')
def stock_stream():
def generate():
while True:
price = get_current_price()
yield f"event: price_update\ndata: {price}\n\n"
time.sleep(1)
return Response(
stream_with_context(generate()),
mimetype='text/event-stream'
)
前端:零 JavaScript。只要一個 HTML 屬性,伺服器就能主動更新頁面。
表單驗證與即時回饋
<form hx-post="/validate-email"
hx-trigger="change"
hx-target="#email-error"
hx-swap="innerHTML">
<input type="email"
name="email"
placeholder="輸入 email"
required />
<div id="email-error" class="error"></div>
<button type="submit">註冊</button>
</form>
伺服器回傳錯誤時,HTMX 自動將錯誤訊息放到 #email-error 元素裡。驗證邏輯全部在伺服器端,前端只需要一個 hx-post 屬性。
與 Django / Flask / Express 無縫整合
HTMX 不挑後端語言。這是它跟 React/Vue 最大的差異:React 需要 Node.js 環境(或者你自己處理 JSX 轉譯),HTMX 只需要能回傳 HTML 的 HTTP 端點。
# Flask 範例
@app.route('/users')
def users():
users = User.query.all()
return render_template('users_partial.html', users=users)
@app.route('/users/<int:user_id>')
def user_detail(user_id):
user = User.query.get_or_404(user_id)
return render_template('user_card.html', user=user)
HTMX 的 philosophy:讓伺服器負責 HTML 渲染,讓瀏覽器負責呈現。兩個責任區分清楚,不需要在中間再加一個 JavaScript 資料層。
誰適合用 HTMX
HTMX 擅長的場景
- 內部工具和後台管理系統:CRUD 操作為主,不需要華麗的前端互動
- 內容網站和部落格:需要伺服器渲染 + 少量動態更新
- 快速原型:不需要建構工具鏈,一個 script tag 就能開始
- 後端工程師主導的專案:如果團隊裡 JavaScript 深度不夠,HTMX 可以降低前端複雜度
- Django/Flask/Rails 愛好者:可以直接用熟悉的 template 系統,不需要另外學 React/Vue
HTMX 不擅長的場景
- 高度互動的應用:如 Figma、Notion、Miro 這類複雜 UI
- 即時多人協作:需要 optimistic updates、conflict resolution
- 需要離線支援:Service Worker 架構的 PWA
- 大型前端團隊:已經有 React 生態系的團隊,遷移到 HTMX 的成本可能高於收益
HTMX vs React:2026 年怎麼選
| 維度 | HTMX | React |
|---|---|---|
| Bundle 大小 | ~14KB gzipped | 典型 React 應用 > 200KB |
| 學習曲線 | 低(只需要 HTML) | 中等到高(JSX、Hooks、Router…) |
| 後端語言限制 | 無 | Node.js 或需要 SSR 設定 |
| 生態系 | 小但專注 | 龐大 |
| SEO 友好 | ✅ 原生 SSR | 需要額外設定(Next.js) |
| 互動複雜度上限 | 中低 | 無上限 |
| 團隊組成 | 後端友善 | 需要專職前端 |
結語:HTMX 的時機
HTMX 不是要取代 React。它是要解決一個不同的問題:當你的應用不需要那麼多前端複雜度的時候,為什麼要承擔 React 的維護成本?
HTMX 2.0 的成熟化(不再需要 IE、Extension 模組化、Web Component 支援)讓這個選擇更加合理。如果你做的是 CRUD 應用、內部工具、或內容網站,HTMX 現在是一個比 2023 年更靠譜的選擇。
2026 年的前端生態,開始出現明顯的分岔:複雜互動的應用走 React/Vue/Svelte;內容驅動和工具類應用走 HTMX 或傳統伺服器渲染 + HTMX。這個分岔會越來越明顯。
延伸閱讀
- Astro 5.0 全面解析 — 與 HTMX 相似的「回到基本面」靜態網站策略
- 2026 前端框架比較 — 框架選擇的完整考量
本文是「2026 前端工具選擇」系列文章之一。如果你對 HTMX 與特定後端框架的整合有興趣,歡迎留言。