In-System Design:在代码与Figma间双向原型的实践方法
In-system design: from code to Figma and back. Prototyping in your real design system
在保持设计系统一致性的前提下,设计师可以在代码原型与Figma画布之间自由切换,无需重新绘制即可复用真实组件。这一被称为 In-System Design 的工作流依赖于严格的命名对齐:Figma 组件必须完全匹配代码中的组件名称和属性(如 Button 及其 variant),使得移动屏幕成为查找而非翻译过程。
具体操作需配置匹配的已发布 Figma 库、连接该库的空原型文件、MCP 连接以及具备执行能力的 AI Agent。从代码到 Figma 时,Agent 读取 Storybook 中的原型并在 Figma 中重建,同时生成包含缺失组件和建议的注释;设计师可通过 Cmd+Y 切换至线框视图,紫色高亮显示所有真实库组件实例,从而快速识别手绘元素或系统偏差。反向流程中,Agent 依据库组件来源和属性设置将 Figma 设计带回代码,非库实例会被列出而非静默重建。
若缺乏代码侧基础设施,团队仍可仅在 Figma 中使用 AI 进行原型设计,只要确保使用连接的库并记录任何手动创建的元素,以便后续开发参考。
In-System Design 3/3
给设计师的实用指南:为什么我不再在画布和代码之间二选一,以及一个原型如何双向流转。

写给那些精通 Figma 但从未编写过生产代码的设计师,以及他们周围的设计系统团队。文末方框内解释了所有技术术语。
我现在有一个在 LinkedIn 上不太讨喜的坦白。是的,我可以用真实的设计系统组件以代码形式制作原型;我很享受这一点,但我仍然希望有时能在画布上工作。在那里,我可以快速调整事物,拆解屏幕,一眼看清整个流程及其层级结构,并排比较三个版本,并把某人拉过来争论这些方案。而且有时候,“提示、等待、观察、再次提示”这个循环让我非常厌烦。有时那是真正的速度,而有时那只是看起来像速度的等待。我想在对的时间使用对的工具。
这不是怀旧;这是关于结果。而且似乎我并不孤单:在一项 斯坦福大学的研究中,并排布局多个版本的设计师比一次只改进一个版本的设计师做出了更好的作品:广告上线时点击量更高,专家评分更高,想法更多样化。这项研究是在 AI 出现之前进行的;然而,提示框显然就像第二组那样运作:一个屏幕,然后是它的更好版本。
优秀的产品源于比较,而不仅仅是精炼,而画布仍然是进行这种比较成本最低的地方。如果你只在代码中工作,那完全没问题。但在一个干净的系统中,你不必为了达到那个目标而放弃画布:相同的组件可以存在于两者之中。如果你的系统根本无法镜像到画布上,那值得仔细审视,因为这通常说明的是系统的问题,而不是画布的问题。
好消息是,我不再需要做出选择。我在代码中原型化的屏幕会变成 Figma 中的真实库组件;我在画布上将其拆解,尝试不同版本,然后发回去,无需任何人重新绘制任何东西。
这就是我所说的 In-System Design(系统内设计):对于每项任务,你选择最能胜任的表面,并且无需离开系统即可达成目标。代码还是画布,由你决定。
本文将逐步展示如何实现这一点,以及往返过程中不断捕获的内容。
我还通过 TJ Pitre、Ian 和 Brad Frost 主持的 AI&Design System Jam Session 演示了这一工作流程:
唯一条件:名称相同,属性相同
只有当每个元素在两侧都指向真实的组件时,原型才能流转。在我的设置中,代码是事实来源,因此 Figma 组件携带代码的确切名称和属性:Button,其变体为 primary、secondary、ghost 或 danger。拼写相同,小写相同,没有“Style: Filled”。我将此称为 In-System Design(系统内设计):使用系统的真实部件,在任何适合问题的表面上进行设计。

有了这一点,移动屏幕就是一次查找,而不是一次翻译。画布上的 ghost button 就是 代码中的 <Button variant="ghost">。当我让一个代理从 Storybook 在 Figma 中重建预订流程时,它放置了 21 个库组件,而没有做出任何视觉决策。如果名称不匹配(Figma 显示 Size = Medium,代码显示 size="md"),就需要有人进行解释,而 AI 会带着极大的自信进行解释。

我已经不再纠结于微小的像素差异了。Figma 和 CSS 不可能在每一笔上完全一致,而且最终的外观反正是在代码中呈现的。如果系统规定是蓝色却出现了绿色按钮,那就是另一回事了,而这正是检查机制要解决的问题。
从任何地方开始,保持在系统内
“系统内设计”意味着我可以从问题所在的地方开始。把 AI 想象成中间的一个枢纽,一侧连接代码,另一侧连接 Figma,所有元素都对齐,然后你告诉它先在哪里构建。“用我们的设计系统在代码中为我构建一个入门流程”可行,同样的请求在 Figma 中也一样可行。无论你从哪里开始,如果你需要另一侧的内容,就告诉 AI 把它放在那里,然后再返回来。只要你保持在系统内,从哪里开始并不重要。

AI 位于中间,一只手臂伸向代码,另一只伸向 Figma。两侧使用相同的组件,因此从哪里开始并不重要。
本文涵盖涉及画布的两个工作流程:从代码到 Figma 再返回的完整往返过程(或反之),以及如果你只有 Figma 这一侧时可以做什么。(要仅使用真实的设计系统在代码中进行原型设计,你需要先进行设置;我在 第 2 部分中解释了这一点。)
1. 从代码原型到 Figma 再返回
你需要:
- 一个与你的代码在名称和属性上完全匹配的已发布 Figma 库。我在第 1 部分中解释了如何使用 MCP 构建这样一个库。
- 一个原型文件:一个新的、空的 Figma 文件,并在 Assets 下连接了该库。
- 与 Figma 原型文件的 MCP 连接,这是一种标准插件,允许 AI 在 Figma 内部工作。我使用 Southleft 开发的 Figma Console MCP,并推荐用于此类工作。
- 以及一个 AI 代理,而不仅仅是聊天机器人。聊天机器人只能看到你粘贴进去的内容。代理可以打开你的项目,运行 Storybook 并为你在 Figma 中工作:例如,Claude 桌面应用中的 Code 标签页(即 Claude Code,我正在使用的工具)、Codex、Cursor 或类似工具。
- 一种使用真实组件在代码中进行原型设计的方法:要么是你的开发人员构建的自定义设计系统 MCP,要么是我在 第 2 部分中展示的 Storybook MCP。
- 访问设计分支上的代码库,这是代码的安全副本,你在其中不会破坏任何东西,也是代码原型被获取和发送回的地方(更多细节见下文)。
从代码到 Figma
我使用 Storybook MCP 进行原型设计。我的 Storybook 有一个 Prototypes 部分,里面有一个课程注册页面原型,我是通过将其连接到 Claude 并要求它设置这个原型制作的:使用真实组件,可点击,在我的笔记本电脑上运行。

在我的示例中,顶部栏不是一个组件,因为我的示例系统是故意做得很小且尚未准备好的。所以我期望在 Figma 中看到相同的情况:所有组件和一个建议的顶部栏。

Figma 文件已打开,库已连接,MCP 已开启。现在我告诉 Claude,也就是我中间的枢纽,我想要什么。我主要使用语音,所以我的提示语有点随意;一旦你的工作流程设置好,大部分内容最终都会变成一个技能:
在我的 Storybook 中有一个名为 Course sign-up 的原型。将其发送到名为 Prototype 的开放 Figma 文件中。使用我的 Figma 组件重建它,设置方式与代码中看到的确切一致。为原型添加注释,说明我需要了解的任何内容,并在旁边附上一个小注记:无法构建的组件、缺失的部分以及我应该知道的任何其他信息。


返回的结果是作为 Figma 屏幕的流程,连接成可点击的原型,并在 Figma 无法展示行为的地方添加了注释。
它留给我的注记
你可能注意到我要求在原型旁边附上一个小注记,这部分至关重要。它列出了使用的组件、手动构建的内容(没有顶部栏组件,因此它组装了一个并说明了情况)、缺失的部分以及建议,例如将那个顶部栏变成一个合适的组件。我在查看屏幕之前会先阅读该注记,你可以根据团队需要了解的内容来塑造它。

我最喜欢的部分:检查组件是否真实
现在是我整个项目中最喜欢的快捷方式:按下 Cmd+Y(Windows 上为 Ctrl+Y)。它将 Figma 切换到线框视图,库组件的每个实例都会以紫色显示,而任何手绘的内容则不会。它成了我新的最佳朋友,因为在一秒钟内我就能看出我是在看我的系统还是系统的绘图。每个库组件都显示为紫色;顶部栏和普通布局框架不显示,且注记正确列出了它们。

从这里开始就是设计工作了,这是我喜欢的一部分:更改文本、移动元素、并排放置三个版本、尝试完全不同的布局、做笔记、与团队讨论。我的库已连接并与代码匹配,因此我从其中添加的任何内容也是真实的。
从 Figma 回到代码
然后回到代码,由于所有组件和 props 都匹配,它可以简单地在 Storybook 中被拾取:
查看开放 Figma 文件中的 Course sign-up 原型并将其带回 Storybook,在代码中更新原型。仅使用系统中的组件,并在编写之前向我展示任何你需要编造的内容。

在返回途中,AI 通过其来源的库组件和设置的 props 读取每个实例,而不是通过其图层名称。任何不是库实例的内容都会被列出,而不是悄悄重建。当我在 Figma 中使用库实例组合一个预订流程并将其发送到代码时,它完全按设计返回了。
往返过程中捕获的问题
我期望往返过程能节省时间。我没指望它能发现 bug,但它一直在发现 bug,因为每次跨越都是对系统的第二双眼睛。
- 21 像素。我将一个注册页面发送到 Figma,Figma 屏幕比 Storybook 中的短 21 像素。我的第一反应是“Figma 又出错了”。其实是代码的问题:两个表单组件将帮助文本包裹在一个保留了浏览器默认边距的段落中,每个自动化检查都放过了它,因为它没有违反规则。Figma 组件具有预期的间距,因此副本捕获了原始问题。
- Figma 正确地改变了流程。我的 Figma 对话框没有插槽,因此表单不能放在里面。流程发生了变化,而不是绕过它:表单变成了自己的步骤,对话框只进行确认。代码保留了这一点,因此两者保持为一个设计。
- 一个被忠实复制的坏习惯。 顶部栏使用了一个空的间隔层来推开元素,因为代码里就是这么做的,而且被粘贴了三次。在代码中,没人注意到这一点。但在画布上,空图层看起来就是它本来的样子,并且可以被 修复。
2. 如果我没有所有这些怎么办?在 Figma 中进行原型设计,指向 代码
还没有代码游乐场、没有设计分支、没有 Storybook MCP?没关系;对于大多数团队来说,目前都是这种情况,因为设计系统不会一夜之间就准备好供 AI 使用。你仍然可以完成画布这一半的工作,而这一点最让人惊讶:你可以直接使用 AI 在 Figma 中进行原型设计,并交付开发者视为真实组件的东西。
你需要什么:上述列表中的第 1 到 4 点。一个匹配的、已发布的库,一个连接了该库的空原型文件,接入 Figma 的 MCP,以及一个 代理。
我打开了一个名为 Prototype 的空 Figma 文件,MCP 已开启。创建一个博客页面的原型,外加一个文章详情页,当我点击其中一篇博客文章时打开。所有需要的内容都使用连接的库,并且始终使用我现有的组件。只有当你绝对找不到某个东西时,才创建它,并告诉我。在原型旁边放一个小注释:你使用了哪些组件,有什么我应该知道的,任何缺口或问题,以及任何你必须编造 的内容。

In-System 意味着所有站点都是可选的附加组件。你选择并使用你拥有或 需要的部分。
与上述相同的习惯:阅读注释,按下 Cmd+Y,然后进行设计,你会得到一个相当不错的原型。如果你的命名是对齐的并且你移交了这个原型,那么重建起来可能比 vibe-coded 的混乱更容易,而且一旦你可以在代码中使用你的设计系统进行原型设计,这就会很好地 衔接起来。
如果 AI 在 Figma 中发明了一个新组件怎么办?
在我的设置中,这还没有发生,因为我告诉它只使用连接的库,并向展示任何它必须编造的东西,但即便如此,在与 AI 合作时,它非常喜欢你提供从未要求过的额外内容。所以即使发生了,也会发生在原型文件中,这是 MCP 唯一工作的文件。整个团队用来设计的主库永远不会被触及,这使得该设置成为一个意外的漂移 阻断器。
有趣的事实:到目前为止,最大的错误来源根本不是 AI。而是我在原型文件中忘记接受的库更新,导致 AI 使用了上周的组件进行构建。发布,接受,然后 提示。
而当代码端稍后准备就绪时,这些屏幕可以像上面那样进入 代码。
我的原型设计技能,以及我在此过程中改进的 方面
首先是一个免责声明,因为它很重要:这一切都不是既定的工作流程。它非常新,仍然是试错过程,在我这边 也是。
在第三次输入相同的指令后,我将它们变成了一个 skill:一套打包好的指令,当出现该任务时 AI 会自动加载。现在我说“使用 skill 将原型从 Storybook 发送到 Figma”,它就会执行其步骤。你可以让 Claude 为你展示并总结一个 skill,然后将其变成你自己的 版本。

带来最大差异的改进包括:
- 缺口在 Figma 图层本身中标记,而不仅仅是在注释中。缺失的导航会变成名称中包含 GAP 的图层(如果你喜欢更响亮一点,表情符号也可以),因此以后绝不会误认为是真实组件。
- Figma 清单。这个想法来自观察开发者为设计系统构建自定义 MCP。他们给 AI 一个小型 JSON 文件,列出存在的内容,这样它就不必每次都在所有代码中爬取,我想,为什么不把同样的方法用于 Figma?我的 Figma 清单列出了每个库组件及其属性,以及 Figma 放置它所需的内部键(名称说明要放置什么,键是拾取它的句柄)。在拥有它之前,一次重建花费了大部分精力去翻阅整个库列表,大约 59,000 个字符,只为找到一个文本样式。现在那只是几行的查找。事实证明这是最大的速度差异,而且它兼作检查 Figma 是否仍与 代码匹配的工具。
- 从代码获取布局名称。组件是家具;布局是排列方式。我的代码库有一个用于排列事物的小型词汇表:stack、cluster、split、columns、grid 和 page。Figma 有自动布局但没有排列名称,因此每个框架最终都变成“Frame 47”,并在回到代码时成为猜测。现在技能会在构建前读取代码中的布局文件,并以相同的方式命名我的自动布局框架,每个间隙都绑定到一个间距变量。并不完美,但开发者能识别结构而不是翻译它。如果这听起来很陌生,请记住在你和团队遇到布局问题的那一天;它可能会激发更好的 想法。
- 画布上的注释,始终保持相同的格式。四个标题:✅ 真实库组件,🟠 手工构建,🔴 Figma 与 Storybook 不匹配之处,💡 值得建议的组件。💡 列表是一个自我编写的待办事项。我的顶栏在每个原型中都是手工构建的,这是系统在礼貌地请求 一个。
- 还有 GAPS.md,记录 Figma 与代码之间每个差异的文件,我在第一篇文章中解释过这一点。
通常的警告词,因为技能可以在你的机器上运行代码:在安装之前先阅读它,或者让开发者先查看一下。如果你愿意看看,我的技能是公开的:storybook-figma-sync 用于原型设计,figma-library-from-code 用于 库。
设计分支:远离生产环境的游乐场

这一切都发生在安全的地方。在一个良好的设置中,开发者为设计师创建一个 design branch(我第一次听到这个想法是来自 TJ Pitre):代码库的一个并行副本,你可以在其中用代码进行原型设计,将其发送到 Figma,在那里自由设计并带回来,而这一切都不会触及真实产品。损坏的状态是可以接受的,未完成的想法也是 可以接受的。
仍然存在交接,而且不是次要的 交接
设计分支永远不会合并到系统中。它是决策的来源,而不是代码的来源。当原型被接受时,开发者会在新分支上正确地重建被接受的部分,团队的检查会在每个人批准之前对每个更改运行。我在 part 2 中详细说明了这些步骤,这是同一个 过程
那么,既然反正都要重建,为什么还要费这个劲?因为大部分工作已经完成了。没人需要去协商什么是按钮或者它使用哪个变体,所以开发者是在转录决策,而不是逆向工程一张图片。剩下的才是真正需要做的决策,而缺口就存在于这些地方:那个手工搭建的顶部栏不是一个需要整理的细节,而是一个团队必须决定、设计并构建的新组件,然后将其镜像到 Figma 中,以便下一个原型可以使用 它。
开始行动:作为设计师,我需要三 样东西
如果你被要求用 AI 制作原型,这就是我会带到你们团队会议上大声宣读的清 单:
- 一个支持 AI、基于上下文的设计系统。干净、语义化,包含 AI 所需的上下文。如果还没有建立,是否有人在推进此事,大家是否意识到其中会有 缺口?
- 一个支持 AI 的原型 MCP。由你们的开发者内部构建,或者是 Storybook MCP,这是为你们构建的相同理 念。
- 一个独立于生产环境的设计分支。访问真实代码,在一个你无法破坏任何东西的地 方。
然后是那份更柔和的清单,其实也是更难执行的一份。开发团队必须知道这件事正在发生并将其设置好。设计和 UX 人员需要了解代码端的情况:使用哪个分支,哪些是禁区,这里的拉取请求(pull request)如何运作。工作流程和思维方式的转变需要时间,而且往往被严重低估。领导层还需要明白,可扩展的 AI 没有速成的构建 工具。
给开发者的一条注记,带着极大的敬意:如果没有设计师看不到的工程支持,这一切都无法奏效。比任何工具都更有用的,是花半小时向设计师展示分支,以及你是如何检查他们交 付给你的内容的。

这未能解决的问 题
- Figma 仍然无法展示行为。错误状态、加载过程以及请求失败时的表现存在于代码中;在画布上,它们只是注释。对于原型来说足够好了,但依然是一个缺 口。
- 它的时效性仅取决于镜像。如果 Figma 库与代码不同步,原型就会携带这种差异,这就是为什么我在构建任何东西之前都会检查同步情况。我的检查通过 Storybook 中的状态页面运行,第一部分解释了它是如何工作的。
- 名称匹配不等于拥有 API。按钮的文本在两处都被称为 children,但在 Figma 中它接受文字,而在代码中它接受任何内容,包括图标或加载指示器。必须有人决定一个属性可以容纳什么,而在我的系统中,这个决定仍然是 未定的。
- 连接会断开。在启动 AI 会话之前先启动 Storybook,并准备好屏幕截图。
- 尚未检查:往返过程中的深色模式和窄屏适 配。
- 它需要一个值得用于原型制作的系统。混乱的库只会给你更快的混 乱原型。
我认为最好的做法
几乎每次会议都有人问我,设计师现在是否应该转向代码。我觉得更有用的问题是:你面前的屏幕是否由你的系统构成。这个问题有一个你可以验证的答案,一边按 Cmd+Y,另一边查看组件列表,而且它并不关心你恰好坐在哪 里。
对我来说,这从来不是关于 Figma 或代码的问题。而是关于使用当天最适合该问题的媒介,以便我能做出最好的产品,并知道无论我做什么决定,在两个地方都算数。有些日子,那是在 Storybook 中的一个提示词。大多数日子,那是画布上并排的三个版本,以及一场关于哪个是正确的的漫长对话,而选择正确的那个仍然是工作的一部分。这就是系统内设计 (In-System Design) 对我的意义:对单一工作流程少一些强烈的观点,多一些能够保持整体一致的产品。
📖 本文中的术语
- Storybook:一个展示代码库中每个组件的网站,实时且可点击。它存在于代码 本身之中。
- MCP (Model Context Protocol,模型上下文协议):一种标准插件,允许 AI 连接到像 Figma 或 Storybook 这样的工具,从中读取数据或在其中执行操作。 The
- Storybook MCP 让它读取你的组件列表;Figma Console MCP(由 Southleft 提供)让它在 Figma 中进行构建。
- Props:组件在代码中的选项(大小、变体、禁用状态)。Figma 称它们为组件属性。
- Instance (实例,Figma):库组件的一个副本,它与源组件保持链接关系。
- Manifest:包含每个组件及其属性和默认值的列表,是生成的而非手动编写的。我的 Figma manifest 对于 Figma 库来说是一样的,外加每个组件的 key。
- Branch:代码库的一个并行副本。design branch(设计分支)专用于设计,永远不会合并到实际 产品中。
- Deterministic check:每次都能给出相同答案的检查,不涉及 AI,比如测试或对比度检查。
- Layout words (布局词汇,来自我的代码库,非标准术语):stack, cluster, split, columns, grid, page。用于描述组件如何排列的名称,同时用于 Figma 框架和代码。
- GAPS.md (我的术语):记录 Figma 与代码之间每一个差异的文件。
- Skill:AI 自行加载的一套打包指令,用于处理重复性任务。安装之前请先阅读它。
- Pull request:更改实际产品的正式提案,在被接受前需经过审查。
- In-System Design (系统内设计,我的术语):使用系统的真实组件进行设计,在适合该问题的任何表面上进行,而不是在一个重建了系统的工具中与系统并列进行设计。
In-System Design: a three-part series.
第 1 部分:构建 AI 就绪的设计系统:Code → Figma
第 2 部分:在设计系统内进行 AI 原型设计
第 3 部分:从代码到 Figma 再返回(你在这里)
关于作者:Christine Vallaure
我是 Christine Vallaure。我做设计,我教书,并且我把大量不合理的时间花在这类文章上。通过 moonlearning.io,我向设计师和团队教授 Figma、设计系统和 AI 工作流程。在此过程中,我在 Figma Config 和 Smashing Conference 等会议上发表演讲,主要探讨设计与代码的交汇点,并且我是 Awwwards 评审团的成员。
我与 AI 助手一起撰写这些文章,素材来自我自己的笔记、录音和代码仓库。思考、示例和观点都是我的,最终的措辞和语气也是我的。
订阅新闻通讯以获取最新动态。
天生就写不出短文章。
系统内设计:从代码到 Figma 再回到代码。在真实的设计系统中进行原型制作最初发表于 Medium 上的 UX Collective,人们通过高亮和回复这篇文章来继续讨论。
原作者保留版权;来源:UX Collective。本站维护者确认获准转载,非公共领域或开放许可证声明。 原文来源(转载授权由站点维护者确认) · 中文译文由 CxHub 客户体验社区生成,并非官方译文。
来源:UX Collective · uxdesign.cc