
# Takumi
**一个将 JSX、HTML 和 node 树转换为图像的 Rust 渲染引擎。无需 headless 浏览器。**
支持从 Node.js、Cloudflare Workers、浏览器或任何 Rust 应用中渲染 OpenGraph 卡片、动态 GIF、视频帧和矢量 SVG。
与 `next/og` 完全兼容。
[](https://www.npmjs.com/package/takumi-js)
[](https://crates.io/crates/takumi)
[](https://www.npmjs.com/package/@takumi-rs/core)
[](#license)
[文档](https://takumi.kane.tw/docs/) · [演练场](https://takumi.kane.tw/playground) · [案例展示](https://takumi.kane.tw/showcase)
## 为什么选择 Takumi
Takumi 是一个用 Rust 构建的渲染 pipeline,专为完成一项任务而生:**将 markup 和 CSS 转换为像素**。它在一个单独的二进制文件内解析 CSS、进行布局、文字塑形(text shaping)、合成图层并编码输出。在渲染同一张 OG 卡片时,headless-Chromium 方案需要消耗约 **300 MB 的 RAM** 以及浏览器的冷启动时间;而 Takumi 只需要**一次函数调用**。
**一套引擎,适用于所有部署目标:**
- **Node.js** 加载原生 binding
- **Cloudflare Workers 和浏览器** 加载 WASM 构建版本
- **Rust 应用** 直接嵌入 `takumi` crate
提供针对 macOS、Linux (glibc 和 musl) 以及 Windows 平台的预编译二进制文件,支持 x64 和 ARM64 架构。
**CSS 支持超越了常规的 OG 图片子集:**
- CSS Grid、block、inline、float
- `::before`、`::after`、`:is()`、`:where()`
- masks、`clip-path`、`backdrop-filter`、blend modes
- `background-clip: text`、conic gradients
- RTL 文本
- Tailwind v4 工具类,包括任意值
## 快速开始
```
bun i takumi-js
```
### 静态图像
```
import { render } from "takumi-js";
import { writeFile } from "node:fs/promises";
const image = await render(
Hello from Takumi
,
{ width: 1200, height: 630 },
);
await writeFile("./output.png", image);
```
### 字体
内置的仅仅是一款作为最后备选的 Latin 字体。其余字体请通过 `fonts` 加载:支持 URL、原始字节或 `googleFonts`。指定 weight 范围或提供 `axes` 条目即可加载 variable font,从而让 `font-variation-settings` 驱动其坐标轴:
```
import { render } from "takumi-js";
import { googleFonts } from "takumi-js/helpers";
const image = await render(
Hello from Takumi
,
{
width: 1200,
height: 630,
fonts: googleFonts([{ name: "Fraunces", weight: "100..900", axes: { opsz: "9..144" } }]),
},
);
```
需要渲染大量图像?只需在 `Renderer` 上注册一次字体即可重复使用。详见 [排版与字体](https://takumi.kane.tw/docs/typography-and-fonts)。
### API 路由(兼容 `next/og`)
```
import { ImageResponse } from "takumi-js/response";
export function GET() {
return new ImageResponse(
Hello from Takumi
,
{ width: 1200, height: 630 },
);
}
```
### 动态 WebP
```
import { renderAnimation } from "takumi-js";
import { writeFile } from "node:fs/promises";
const animation = await renderAnimation({
width: 400,
height: 400,
fps: 30,
format: "webp",
scenes: [
{
durationMs: 1000,
node: (
),
},
],
});
await writeFile("./output.webp", animation);
```
### 矢量 SVG
```
import { renderSvg } from "takumi-js";
import { writeFile } from "node:fs/promises";
const svg = await renderSvg(
Hello from Takumi
,
{ width: 1200, height: 630 },
);
await writeFile("./output.svg", svg);
```
### Rust
```
cargo add takumi
```
从 [Rust 示例](./example/rust) 开始。
## 对比
| 特性 | `next/og` (Satori) | Takumi |
| :--------------------------------- | :----------------: | :-----------------------------------------------------------: |
| **运行时 (Runtime)** | Node / Edge | Node, Edge, CF Workers, Browser, **Rust crate** |
| **模板输入** | JSX / React | JSX, HTML strings, 来自任何语言的 JSON node 树 |
| **布局 (Layout)** | Flexbox | Flexbox, **CSS Grid**, block, inline, float |
| **选择器 (Selectors)** | 有限支持 | 复杂选择器, `:is()`, `:where()`, `::before`, `::after` |
| **`backdrop-filter`, blend modes** | ✗ | ✅ |
| **动画输出 (Animated output)** | ✗ | **WebP / APNG / GIF / 视频帧** |
| **矢量 SVG 输出** | ✅ 原生支持 | ✅ **外加栅格与动画输出** |
| **Headless 浏览器** | ✗ | ✗ |
| **`ImageResponse` API** | ✅ 原生支持 | ✅ **完全兼容** |
前往 [image-bench.kane.tw](https://image-bench.kane.tw) 对比各提供商的渲染输出结果。
## 谁在使用 Takumi
- [Dcard](https://dcard.tw) 渲染帖子分享图像
- [TanStack](https://tanstack.com) 为其文档渲染 OG 图像
- [Fumadocs](https://fumadocs.dev) 生成其文档的 OG 图像
- [Nuxt OG Image](https://nuxtseo.com/docs/og-image/renderers/takumi) 内置 Takumi 作为渲染器
- [Luma](https://lu.ma) 渲染活动分享图像
- [shiki-image](https://github.com/pi0/shiki-image) 将语法高亮代码转换为图像
更多项目请见 [案例展示](https://takumi.kane.tw/showcase)。Takumi 是 [Vercel OSS Program](https://vercel.com/oss) 的一部分。
## 核心架构
Takumi 会将任何模板转换为包含三种节点类型的 **node 树**:`container`、`image` 和 `text`。该树会依次经过以下处理:
1. **布局** 通过 [taffy](https://github.com/DioxusLabs/taffy) 实现:支持 Flexbox、Grid、block、float、`calc()`、绝对定位、z-index
2. **文字塑形** 通过 [parley](https://github.com/linebender/parley) 和 [skrifa](https://github.com/googlefonts/fontations/tree/main/skrifa) 实现:支持 WOFF/WOFF2 字体、emoji、RTL、多重内联块(multi-span inline blocks)
3. **合成**:处理层叠上下文、blend modes、filter、transform,并通过 [resvg](https://github.com/linebender/resvg) 处理 SVG
4. **输出**:支持输出静态格式(PNG、JPEG、WebP、ICO);动画格式(GIF、APNG、WebP);以及用于视频 pipeline 的原始 RGBA 帧
由于其输入契约是一个 node 树,因此任何能序列化为 HTML 或 JSON 的模板系统都可以作为数据源:React、Svelte、Vue、纯字符串,或是任何语言编写的自定义序列化器。
一条 **时间轴** 贯穿整个 pipeline:渲染器接收一个时间戳,因此 PNG 是 `t=0` 时刻的树状态,而 GIF 是同一棵树在 `t` 上的采样集合。CSS `@keyframes`、`animation` 简写属性,以及 Tailwind 动画工具类(`animate-spin`、`animate-bounce`、任意值)均会在渲染时进行解析。
同样的布局逻辑还驱动了第二个后端:`renderSvg()`(Rust 中的 `render_svg`,隐藏在 `svg-backend` feature 之后)会生成一份由 `
`、``、渐变和字形轮廓构成的真实 `