关于 nudg
nudg 是一套基于 JSON 的格式、运行时和工具,用于描述并检查 Web 与原生应用中的 UI 交互。它面向开发者和编码 Agent,提供模拟、渲染及前后对比,便于审查动效修改。
主要功能
- 01用 JSON 文件描述状态和动效
- 02TypeScript、Swift、Kotlin 行为一致
- 03常见交互模式的配方和预设
- 04验证、模拟、绘图、渲染与评析
- 05并排比较交互修改
- 06适配 Web 和原生平台
适用场景
- 01通过自然语言修改调校交互
- 02发布前检查交互行为
- 03比较不同平台运行时的动效
- 04为常见 UI 模式生成起始文件
MCP 相关
nudg 内含供 Agent 使用的 MCP 服务,可获取配方并验证、模拟、渲染、比较、评析或观察交互。可通过 `npx -y @nudg/core mcp` 添加为 MCP 服务。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
11收录的工具列表 · 更新于 3 天前
此工具无需参数。
详细介绍
nudg 用一个小型 JSON 文件描述组件旁边的 UI 交互:交互状态、状态之间切换的事件,以及切换过程中的动效。你的 AI 编码工具会编辑这个文件,nudg 会检查修改,然后由一个精简的运行时在应用中播放交互。
把它想成乐谱
.nudg.json 文件是乐谱 | 哪些部分会动、处于什么状态,以及如何变成那样 |
| 运行时是演奏规则 | TypeScript、Swift 和 Kotlin 以相同方式演奏同一份乐谱,并通过共享的一致性测试套件验证 |
| 你的 AI是编曲者 | “更有弹性”只需更改一个标记,而不是整首曲子 |
| 你是导演 | 并排观看修改前后的效果,选出更好的版本 |
说声“更有弹性”,对比前后效果,再做判断
"animate": {
- "knob.x": { "spring": { "duration": 0.35, "bounce": 0.25 } },
+ "knob.x": { "spring": { "duration": 0.35, "bounce": 0.6 } },
日常用语会对应到单个字段:更有弹性对应 bounce,更慢对应 duration。组件代码不会改变。
它还会主动向你展示效果。nudg_compare 会在相同的点击操作下播放两个版本,先说明你是否能察觉差异(“变化明显:knob.x 的移动距离最多相差 2.1 个单位,稳定时间晚了 0.23 秒”,或 “人眼察觉不到;请先查看夸张版本”),然后并排展示前后的实际画面帧:Web 应用中在浏览器里展示,在应用自带的视图中则分别通过 SwiftUI 和 Compose 展示。你只需看着画面做判断。
一个文件描述完整交互
这是上面的开关,包含完整定义:
{
"nudg": "1.1",
"targets": ["knob", "track"],
"values": { "knob.x": 0, "track.color": "#D1D5DB" },
"animate": {
"knob.x": { "spring": { "duration": 0.35, "bounce": 0.25 } },
"track.color": { "tween": { "duration": 0.2, "ease": "out" } }
},
"initial": "off",
"states": {
"off": { "when": { "track.tap": "on" } },
"on": {
"set": { "knob.x": 20, "track.color": "#4ADE80" },
"when": { "track.tap": "off" }
}
}
}
- 状态说明位置。 在
on状态下,旋钮位于 20,轨道为绿色。 animate说明方式。 旋钮以弹簧动效移动到位;颜色通过渐变过渡。when说明状态切换的触发条件。 点击轨道。
如果在动效过程中打断它,弹簧会把当前速度带入新的运动方向,无需编写额外代码。
组件会按名称绑定各个部分,nudg 则在这些部分上播放文件中的交互:
import { useNudg } from "@nudg/core/react";
import toggle from "./toggle.nudg.json";
function Toggle() {
const { bind } = useNudg(toggle);
return (
<button ref={bind("track")} aria-label="Wi-Fi" style={{ position: "relative", width: 52, height: 32, padding: 0, border: 0, borderRadius: 16 }}>
<span ref={bind("knob")} style={{ position: "absolute", top: 4, left: 4, width: 24, height: 24, borderRadius: "50%", background: "#fff" }} />
</button>
);
}
外观由你决定(尺寸、形状、旋钮静止时的位置);文件负责移动它。数值会直接应用到元素样式,因此元素移动时组件不会重新渲染。使用 Vite 时,将 nudg() 从 @nudg/core/vite 添加到插件中:文件会在构建时编译,存在错误的文件会导致构建失败,而 nudg 的压缩后体积约为 14 kB(gzip),而非 28 kB。不使用 React?DOM 适配器会改为绑定 data-nudg="knob" 属性;请参阅使用 nudg。
一次导入,获得原生体验
nudg 将各平台自带的动效以相同格式作为库提供:SwiftUI 的弹簧动效,以及从公开值复制而来的 Material 3 动效令牌。它们共享 standard、quick 和 playful 等通用名称,因此只需一行差异,就能将交互从 iOS 风格切换为 Android 风格:
- "import": ["./motion/apple.nudg.json"],
+ "import": ["./motion/material-expressive.nudg.json"],
"animate": { "knob.x": "standard", "track.color": "fade" }
请参阅各平台的原生动效,查看所有名称和值。
UI 词汇成为标准交互
人们通常不会要求设置 duration: 0.35 和 bounce: 0.2。他们会说“把它做成 FAB”“用标签页”“以底部工作表的形式显示”“让这一行可以滑动删除”,或者“让这个 toast 更有 iOS 的感觉”。nudg 旨在让这些说法映射到可复用的交互模式,而不是让 AI 临时猜测并编写一次性代码。
设计方向以移动端优先:fab、tab-bar、bottom-sheet、toast / snackbar、swipe-row、carousel、switch、slider、dialog、list、grid、voice-chat、video-call、camera、music-player 和 video-player 等模式,都应具备符合预期的组成部分、状态、手势和平台动效。宿主仍负责标记、布局和设备 API;nudg 提供交互行为,供 AI 编辑、供人判断。
human UI words
-> semantic pattern
-> states, events, targets and motion
-> compare / observe
开始使用
npm install @nudg/core
npx nudg recipe toggle --source > toggle.nudg.json # a validated starter; `npx nudg recipe` lists them all
通过 MCP 向 AI Agent 提供 nudg 工具。这适用于 Claude Code;任何 MCP 客户端都可以运行相同的命令:
claude mcp add nudg -- npx -y @nudg/core mcp
或者直接在文件上使用 CLI:
npx nudg validate toggle.nudg.json
npx nudg simulate toggle.nudg.json --send [email protected]
需要 Node 22.4 或更高版本。所有命令和选项请参阅使用 nudg。
自然语言 UI 从配方开始
nudg 将熟悉的 UI 术语映射到带版本的交互契约,而不是让 AI 重新发明它们。配方会列出预期的组成部分、状态、事件、连续输入、宿主职责、动效、已知的格式限制,以及经过验证的起始模板:
npx nudg recipe "video chat"
npx nudg recipe sheet --json
npx nudg recipe toggle --source > toggle.nudg.json
目录涵盖所有已发布示例,从开关、标签页和工作表到语音聊天、相机和媒体播放器。格式尚无法表达的模式(例如菜单、加载指示器和屏幕切换)也会列出,但不提供起始模板,让 AI 说明哪些部分由宿主实现,而不是自行臆测。运行时,配方仍是普通的 nudg 文档;它们引导生成过程,但不会让核心变成特定组件专用。
简单情况只需一行
按压、悬停、切换或 toast 都不需要文件。预设是可直接使用的 nudg 文档:
import { useNudg, presets } from "@nudg/core/react";
const { bind } = useNudg(presets.press({ scale: 0.96 }));
<button ref={bind("button")}>Save</button>
import { playDoc } from "@nudg/core/dom";
import { presets } from "@nudg/core";
playDoc(presets.toast({ duration: 3 }), document.querySelector(".toast"));
选项不够时,nudg preset press > press.nudg.json 会将相同的文档写入文件,之后你就可以自行编辑,也可以交给 AI 编辑。
AI 会检查自己的工作
Agent 无法观看动画,因此 nudg 会用文字和图片告诉它发生了什么:
| 工具 | Agent 能获得什么 |
|---|---|
recipe | 针对 toggle、sheet 或 video chat 等人类 UI 术语提供标准交互契约和经过验证的起始模板。 |
validate | 每个问题都带有稳定的代码、JSON 指针,以及说明如何修复的提示。 |
simulate | 一系列事件随时间变化的状态和值:“旋钮过冲到 20.57,并从 0.84 s 起静止”。 |
plot | 每项属性的动效图,例如下方所示的图。 |
render | 在无头浏览器中捕获的组件实际画面。 |
compare | 在相同点击操作下对比修改前后:人是否能察觉变化、并排显示两者,以及可慢速播放它们的页面。将其指向正在运行的应用,它就会在浏览器中打开。 |
critique | 动效是否出色,而不只是有效:过慢、按压反馈延迟、不可见、淡出弹跳、退出缓慢、超时过短、没有 Escape。每项都会给出修复建议及其来源。 |
observe | 宿主实际情况:真实页面,每帧都经过点击和测量,并与文件进行比对。“元素在 0.18 s 时离开页面;释放状态从未显示。” |
示例网站的交互体验区也提供相同的实时评判视图:与原版对比会并排播放原版和你的修改;点击任一方都会同时触发两者;慢动作是一个选择项;评判结果会随着输入实时更新。
toggle 的 nudg plot 输出:旋钮仍在移动时再次点击。弹簧会平滑地反向运动,而不是重新开始。
工作原理
nudg 核心从不绘制任何内容。事件输入,属性值输出,轻量适配器再将它们应用到你的视图:
your app (web, React Native, SwiftUI, Compose, ...)
│ events: tap, drag, hover, focus, app events
▼
┌──────────────── nudg core ────────────────┐
│ states + clock + motion math (headless) │
└────────────────────────────────────────────┘
│ values: knob.x = 18.3, track.color = #4ADE80
▼
adapter sets them on your views
- 确定性。 相同时间发生的相同事件总会产生相同的值,因此可以像测试其他代码一样测试动画。
- 可移植。 任何能够设置属性并发送事件的平台都可以运行 nudg。规范和与语言无关的一致性测试套件定义了行为,而非某个具体实现。
- 只有 JSON。 无需新语法,无需可视化编辑器,差异易于阅读。当前的 JSON Schema 可为编辑器提供自动补全,软件包还会将其最新版本导出为
@nudg/core/schema.json。
为什么要用
交互动画通常保存在用专用可视化编辑器制作的二进制文件中。AI 无法编辑它们,审阅者看不懂差异,而且每次小改动都得回到那个工具中完成。nudg 将交互作为文本保存在你的代码仓库中,你现有的 AI 编码工具已经可以在其中工作。了解更多设计理念。
状态
稳定。 1.5 版(格式 1.1)已发布到 npm,包含每种语义配方的入门示例,以及轻触、悬停、拖动、抛掷和滑行、捏合、长按和双击、键盘事件、滚动方向和输入阈值、可暂停计时器、连续应用和滚动输入、测量布局、入场关键帧、循环、交错延迟、屏幕过渡、声明式宿主接口、减少动态效果、类型安全的宿主名称(nudg generate)、所有平台统一的一个“动画结束”回调(onSettle)、原生平台的屏幕阅读器激活和调整、无闪烁的服务端渲染,以及适用于 DOM、React(可桥接 MUI、Radix 和 shadcn/ui)、React Native、SwiftUI 和 Jetpack Compose 的适配器。在 1.x 系列中,文件和 API 只会增加;任何破坏性改动都要等到 2.0。请参阅更新日志。
路线图记录了开发优先事项和各阶段状态,涵盖组件交互、屏幕和流程、原生适配器,以及探索中的独立内容。移动优先的语义模式基于这一发展路线构建。
文档
- nudg 格式:完整语法。
- 使用 nudg:CLI、MCP 服务、适配器(DOM、React、React Native、SwiftUI、Compose)以及平台动态效果。
- 设计:原则、范围、决策和未解决的问题。
- 路线图:开发计划、当前状态和完成标准。
- 覆盖范围:该格式可以表达的内容,按触发条件、响应和结构划分,以及它支持的平台。
- AI Agent 指南:一页了解该格式;编辑约定列出 AI 工具可以依赖的所有内容。
- 开发日志:构建 nudg 时遇到的问题及其解决方法。
配合你已在使用的组件
nudg 为你已有的组件添加动态效果,而不是替换它们。对于 shadcn/ui、Radix、Headless UI 或 React Aria,useNudg(file, { watch: true }) 会跟随它们显示的状态(data-state、aria-*)。对于 MUI、Ant Design 或 React Bootstrap,nudgTransition(file) 可接入它们的过渡插槽。库负责行为和无障碍支持;文件负责定义动画的感觉,AI 可以调整,你也可以评估。请参阅使用 nudg。
帮助 nudg 变得更好
nudg 的目标是让一次动态效果修改只需一轮:你说出一个词,查看前后效果,然后作出判断。它是否达成目标,会在你的设备上衡量,并记录在本地日志中;日志不会自行离开你的设备。如果你在使用 nudg,请不时分享使用情况:
npx @nudg/core log --share
它会准确显示将要发送的内容(仅计数:每次修改的轮数、评判结果、工具调用次数;不包含文件名、路径或代码),并为你打开一个 GitHub issue,供你查看并提交。
参与贡献
欢迎提交问题和拉取请求。nudg 在编写代码前会先进行设计,因此,除修复错误外,如果你想构建某种交互,请先创建一个问题,讨论你的想法。请参阅 CONTRIBUTING.md。
许可证
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。