项目详情

htmx

high power tools for HTML——把超文本补完

GitHub 地址 官网文档 0BSD JavaScript · ~14KB

更新于 2026-08-30 · 数据来源:GitHub API(采集于 2026-08-30)

← 返回汇总
项目速览

一句话定位

不写 JavaScript,让 HTML 自己长出交互

直接在 HTML 属性里(hx-get / hx-post / hx-swap…)访问 AJAX、CSS Transitions、WebSocket、SSE——服务端返回 HTML 片段而非 JSON,零构建、零 hydration、零客户端状态管理。适合想逃离 SPA 复杂度、以服务端为中心的 Web 团队;也是理解 REST 本源(HATEOAS)的最佳工程教材。

项目速览

核心数据

49k
Stars
458
贡献者
~14KB
min.gz 零依赖
6 年
持续演进(2020 起)

1.6k forks · 前身 intercooler.js(2013)· 当前 v2.0.10 · 0BSD 许可(比 MIT 更自由)· 作者 Carson Gross 同期维护 hyperscript、著《Hypermedia Systems》· 官网附 essays 专栏沉淀超媒体方法论

为什么存在

README 里的灵魂四问

  • 为什么只有 <a> 和 <form> 能发 HTTP 请求?
  • 为什么只有 click 和 submit 事件能触发请求?
  • 为什么只有 GET 和 POST 可用?
  • 为什么只能替换整个屏幕?

移除这四个任意约束,htmx 就「完成了 HTML 作为超文本的使命」。

任何元素可发请求、任何事件可触发、全部动词可用、任意局部可替换——HTML 原本就差这四步就能成为完整的应用超媒体。

README 结尾的一首 haiku,是整个项目的气质注脚:javascript fatigue: longing for a hypertext already in hand(JS 疲劳:渴望一种早已在手的超文本)。

核心理念

SPA vs 超媒体:两种世界观

SPA 世界观(JSON API) 浏览器 SPA 组件树 + 状态管理 + 路由 JSON API REST-ish 端点 JSON 状态在客户端维护 · 构建链:bundler / TS / npm 生态 · 双份逻辑:服务端模板 + 客户端渲染 · 状态同步:缓存失效两大难题 · 应用状态与超文本分离(HATEOAS 缺席) · 强项:离线、复杂本地交互、富编辑器 htmx 世界观(超媒体) HTML + hx-* 属性 htmx ~14KB 驱动 服务端模板 任意后端语言 HTML 片段 状态由服务端下发(HATEOAS) · 零构建:script 标签即用 · 单份逻辑:服务端一处渲染 · 状态同步:刷新即真值 · 应用状态编码在超文本里(Fielding 本意) · 弱项:依赖网络往返、复杂本地交互受限
超媒体:HTML 既是数据也是应用状态 SPA:HTML 降级为空壳,状态搬进 JS
核心机制

一次 hx-get 的完整生命周期

① 事件触发 hx-trigger 声明 (delay/once/changed) ② 组装请求 hx-vals / hx-headers + 自动带上元素值 ③ AJAX GET/POST/PUT/ DELETE/PATCH 全动词 ④ 响应 → 定位目标 → swap hx-target(默认自身)+ hx-swap 策略 6 种交换位置 ⑤ settle:CSS 过渡窗口 新旧 DOM 差异触发 transition 平滑动画无需 JS ⑥ hx-push-url 局部更新也进历史栈 后退按钮天然可用
主链路(实线) 网络与动画增强(虚线:settle 过渡 + 历史管理)
核心机制

两行代码的哲学

<script src="https://cdn.jsdelivr.net/npm/htmx.org@2/dist/htmx.min.js"></script>

<!-- 这就是 htmx 的全部入门成本 -->
<button hx-post="/clicked" hx-swap="outerHTML">
  Click Me
</button>
核心机制

hx-swap 六式

交换模式语义典型用途
innerHTML替换目标内部内容默认;局部刷新列表/面板
outerHTML目标整体被响应顶替按钮自替换、行内编辑落定
afterbegin插入为目标第一个孩子新条目置顶(feed 流)
beforeend追加为目标最后一个孩子无限滚动加载更多
beforebegin / afterend插到目标前/后做兄弟在元素旁插入提示/行
none不交换(只执行副作用)纯动作(点赞计数由响应头驱动)

配合 hx-target(CSS 选择器 / closest 语法 / this)决定「换哪里」,hx-swap 决定「怎么换」——组合出所有局部更新需求,整页刷新从此退休。

核心机制

hx-trigger:事件系统军火库

<!-- 任意元素、任意事件,全部声明式 -->
<div hx-get="/mouse_entered" hx-trigger="mouseenter">悬停加载</div>

<input hx-get="/search" hx-trigger="keyup changed delay:500ms"/>
<!-- 值变了才触发 + 500ms 防抖:搜索框的工业标准写法,一行 -->

<button hx-post="/vote" hx-trigger="click throttle:1s">投票</button>
<!-- 1 秒节流:防连击,还是一行 -->

<div hx-get="/dash" hx-trigger="every 5s">仪表盘</div>
<!-- 轮询:every 5s,仍然一行 -->

<form hx-post="/save" hx-trigger="submit from:body">…</form>
<!-- from: 换监听源;once / delay / changed 自由组合 -->

防抖、节流、轮询、事件委托、一次性触发——这些 SPA 里要引库或手写的时序控制,在 htmx 里是 trigger 规范的一部分。Playground 里可以亲手调这些参数。

生态

扩展 + hyperscript:克制后的纵深

官方扩展(30+)
  • ws / sse:WebSocket、Server-Sent Events 直通 HTML——服务端推片段即实时 UI
  • response-targets:按响应状态码(4xx/5xx)路由到不同目标——错误处理声明式化
  • path-params / json-enc:需要 JSON 时也留了门——承认现实世界的混合需求
  • client-side-templates / morphdom-swap:JSON 转 HTML、DOM diff 交换——按需加磅,不加不付钱
hyperscript(姊妹语言)
<button _="on click toggle .red on me">
  变红
</button>

同一作者的 inline 脚本语言,为「标记里写小逻辑」设计——htmx 负责与服务端交互,hyperscript 负责纯本地小动作,两者互补且各自独立可选。

工程与演化

六年三幕:intercooler → htmx 1.x → 2.x

适用场景

适合谁用

风险提示

需要警惕(作者自己也承认)

在线体验

在浏览器里玩一个迷你 htmx 内核

Playground 从零实现 htmx 的核心语义:写带 hx-* 属性的标记 → 点击真的触发(mock)请求 → 看 hx-swap 六种交换位置的实时效果 → 用 hx-trigger 的 delay/throttle 调防抖节流——右侧同步打印每次「网络往返」的完整决策日志。

打开 Playground

纯前端实现,零网络依赖 · swap 六模式 + trigger 解析 + 防抖节流语义均经真值表对拍验证

潜力评估

未来空间

htmx 改变的不只是写法,是行业对话的坐标系——「要不要 SPA」从此有了体面的否定答案。Web 平台演进(View Transitions、hotwire 系竞争)会持续挤压它的独特性,但「HTML 补完主义」的哲学坐标与教学价值长存:它证明了复杂度是可以被拒绝的,而拒绝本身可以成为 49k stars。

理念驱动 · 自成流派 6 年稳态演进 测试纪律严格 平台演进挤压 主流惯性阻力

1 / 15