satori
用 JSX 代码生成 SVG 图片,Vercel 开源的前端图片渲染利器
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
用 JSX 代码生成 SVG 图片,Vercel 开源的前端图片渲染利器
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
想象一下,你正在为博客文章、社交媒体动态或者产品页面制作配图。每次都需要打开设计工具(Figma、Photoshop),手动调整文字、颜色、布局,然后导出图片——这个过程重复而枯燥。更麻烦的是,每次修改内容都要重新走一遍流程。
Satori 正是为解决这个痛点而生的。它由 Vercel 出品,是一个将 JSX 代码直接渲染为 SVG 图片的开源工具。换句话说,用写代码的方式生成图片——就像程序员写代码一样,设计师和开发者也可以用 JSX 语法精确描述每一张图的布局、文字、颜色,然后通过 Satori 一键生成 SVG。
这种方式的强大之处在于:SVG 是矢量格式,放大缩小不失真;代码即模板,改内容只需改参数;输出的 SVG 可以进一步通过其他库(如 @resvg/resvg-wasm)转为 PNG/JPEG,完美适配 Open Graph 社交分享图、动态新闻卡片、邮件配图等场景。
图1:Satori 项目封面
Satori 由 Vercel 团队内部开发,用于解决 Vercel 平台自身大量动态图片生成需求。团队成员 Shu Ding(@shuding)是核心贡献者,他在 Vercel 负责边缘函数和图片处理相关工作。在日常开发中,Vercel 需要为每个部署的网页自动生成 Open Graph 图片,传统方式要么依赖外部图片服务,要么需要启动完整的浏览器环境渲染。
为追求极致性能和部署便利性,Vercel 决定从底层自研一个纯 JS/TS 的图片渲染引擎,将 JSX 语法作为布局描述语言,直接输出 SVG。这项内部工具在验证可行性后开源,迅速获得社区认可,截至目前已收获超过 13,000 颗星。
Satori 的诞生折射出一个趋势:工程基础设施正在向代码化、可编程化演进。过去需要专业设计工具完成的图片工作,如今可以通过几行 JSX 代码精确控制,这一变化降低了图片生成的门槛,也为自动化、规模化内容生产打开了新的想象空间。
Satori 的工作流程分为三个阶段:
第一阶段:JSX 解析与虚拟 DOM 构建
用户编写的 JSX 代码首先被 React 的 JSX 编译器处理为虚拟 DOM 节点。Satori 提供了一个自定义的 JSX runtime,支持在不引入 React 的情况下直接写 JSX。这意味着你可以在纯 Node.js 环境、甚至浏览器环境中使用 JSX 语法,而不必搭建完整的 React 运行时。Satori 的 JSX runtime 通过 @jsxImportSource satori/jsx pragma 启用,属于实验性功能。
第二阶段:Yoga 布局引擎计算盒模型
解析后的虚拟 DOM 节点被送入 Yoga(Facebook 开源的跨平台布局引擎,也是 React Native 的布局内核)进行排版计算。Yoga 实现了 Flexbox 规范,Satori 将 JSX 中的 CSS 属性翻译为 Yoga 的布局指令,计算出每个元素的精确坐标和尺寸。由于 Satori 内嵌了 yoga.wasm(Yoga 的 WebAssembly 编译版本),可以在任何支持 WASM 的环境中高性能运行,无需调用浏览器 DOM API。
第三阶段:SVG 生成
布局计算完成后,Satori 的 builder 模块遍历所有节点,根据节点类型生成对应的 SVG 元素。文本节点通过 <text> 和 <tspan> 实现,图片节点生成 <image> 元素,背景色和边框生成 <rect>。每种 CSS 属性(颜色、字体大小、边距、内边距)都有一一对应的 SVG 属性映射。整个渲染管线的输入是一个 JSX 组件加上一组字体配置,输出是一段 SVG 字符串,整个过程在 Node.js 环境中毫秒级完成,内存占用极低。
Open Graph 社交分享图
这是 Satori 最核心的应用场景。在 Vercel 平台,当你部署一个 Next.js 项目时,平台可以调用 Satori 动态生成该项目的 OG 图片——包含项目名称、描述、作者头像等信息,全部代码化,每次部署自动生成,无需人工设计。开发者只需定义好 JSX 模板,Satori 负责渲染。
动态新闻卡片与邮件配图
内容平台和媒体网站每天需要生成大量带有标题、摘要、来源标识的图片。Satori 让这个过程完全自动化:内容数据通过模板变量注入,JSX 描述卡片设计,Satori 批量渲染,SVG 直接嵌入邮件或网页。
文档与教程的代码驱动图片生成
技术博客和文档网站可以用 Satori 生成统一的文章封面、代码高亮区域图、以及带有项目 Logo 的章节配图。由于 SVG 放大不失真,在高分辨率屏幕和打印场景下都表现优异。
Satori 的代码库结构清晰,采用 monorepo 架构,通过 pnpm workspace 和 Turborepo 管理:
| 目录/文件 | 职责 |
|---|---|
src/builder/ | SVG 元素构建器,将布局结果转为 SVG 标签 |
src/handler/ | 事件和样式处理逻辑 |
src/jsx/ | 自定义 JSX 运行时,支持无 React 使用 |
src/layout.ts | Yoga 布局引擎封装 |
src/parser/ | CSS 属性解析与转换 |
src/text/ | 文本排版与字体渲染 |
src/font.ts | 字体加载与度量 |
yoga.wasm | Yoga 布局引擎 WebAssembly 二进制 |
playground/ | 在线 Playground,基于 Next.js + Monaco Editor |
代码质量方面,仓库使用 TypeScript 全程类型安全,有完整的 ESLint + Prettier 规范,有 Vitest 单元测试,CI 流程包含类型检查、格式校验和测试。代码注释清晰,导出 API 简洁易用(satori(jsxElement, options) 两参数模式)。值得注意的是,Satori 使用了 WebAssembly 来运行 Yoga 引擎,这保证了跨平台的一致性和高性能。yoga.wasm 被打包在 npm 包中,安装后开箱即用,无需额外下载。
Vercel 提供了在线 Playground,基于 Next.js + Monaco Editor 构建,无需本地安装即可体验 Satori 的全部功能。左侧写 JSX 代码,右侧实时预览 SVG 输出,还可以切换语言(JS/TS/JSX)、下载 SVG、导出 PNG。Playground 还支持输出 PDF 格式。
本地安装也非常简单:
pnpm add satori
Satori 本身是纯 TS 库,通过 npm/pnpm 安装后以 ESM 模块引入,不依赖任何容器或特殊环境。只要有 Node.js >= 18 即可运行。
Satori 并不是万能的图片渲染工具,它有以下已知限制:
CSS 支持不完整:Satori 只实现了部分 CSS 属性,不支持所有现代 CSS 特性(如 CSS Grid 的完整功能、CSS 动画、CSS 变量驱动的动态样式)。高级布局需求需要查阅官方文档确认支持情况。
不支持交互式 React:JSX 仅用于描述静态布局,不支持 useState、useEffect 等 React Hooks,也不支持事件处理。Satori 渲染的是「无状态的 JSX」,不是完整的 React 组件。
字体管理复杂:字体需要手动加载(通过 fs.readFile 或 fetch),且每次渲染都要提供字体数据。对于需要动态字体的场景,配置相对繁琐。
SVG 格式局限:输出是 SVG,在某些不支持 SVG 的场景(如某些社交平台的 OG 图片要求)需要额外一步将 SVG 转为 PNG,增加了依赖复杂度。
Satori 的出现代表了一个更大的趋势:图片生成的代码化和自动化。在 AI 时代,内容的规模化生产是刚性需求,而 Satori 用最朴素的方式——代码——解决了图片模板化生产的问题。它的 Star 增长曲线显示,自从 2022 年 Vercel 宣布将 Satori 用于 OG 图片生成后,社区关注度持续上升,成为前端工具链中一个小而美的精品项目。
未来,随着 AI 生成内容(AIGC)的普及,Satori 有可能与 AI 模型结合——AI 生成卡片文案,Satori 负责渲染,二者共同构成全自动内容配图流水线。对于需要大量生成社交分享图、产品卡片、数据图表的团队来说,Satori 是值得加入工具箱的基础设施。