大家好,我是何三,独立开发者
一张社交媒体分享图,后台要启动一个 300MB 的 Chrome 浏览器。这听起来是不是有点离谱?
但这就是过去几年里,所有用 next/og 或者 Puppeteer 生成 OG 图片的人每天都在干的事——每次用户分享一篇文章,你的服务器就得默默拉起一个完整的浏览器实例,渲染完了再关掉。300MB 内存就为了跑一张 1200×630 的图。
Takumi 干了件很绝的事:把这个过程缩成了一个函数调用。
项目地址:https://github.com/kane50613/takumi
它到底做了什么?
说人话就是——Takumi 在 Rust 里实现了一个完整的渲染管线,从 CSS 布局到文字排版再到像素输出,全部塞进了一个二进制文件。
以前你要生成一张 OG 图:
- 启动 Chrome/Puppeteer(300MB RAM)
- 加载页面(再吃几十 MB)
- 截屏输出
- 关掉浏览器
现在你只需要:
import { render } from "takumi-js";
const image = await render(
< div tw="w-full h-full flex items-center justify-center bg-gradient-to-b from-blue-100 to-red-50">
< h1 tw="text-6xl font-bold">Hello from Takumi< /h1>
< /div>,
{ width: 1200, height: 630 },
);
一个 render() 搞定。没有浏览器,没有 300MB 开销,没有冷启动延迟。
说实话,我第一次看到这个的时候真的愣了一下——没懂作者为什么非要用 Rust 从头写一套渲染引擎。后来仔细一想,如果不是 Rust,还真做不到这个效果。
不只是 next/og 的替代品
Takumi 可以当作 next/og 的即插即用替代品——ImageResponse API 完全兼容。但它的能力远不止于此。
这个东西怎么说呢……就是那种……越用越觉得离谱的工具。
我来列几个让我直接惊到的能力:
支持 CSS Grid。 next/og(底层是 Satori)只支持 Flexbox,想排个网格布局你得自己算。Takumi 直接把 Grid 支持做好了,grid-template-columns、grid-template-rows,随便用。
支持动画输出。 你没看错,它能生成动图——WebP、APNG、GIF,甚至可以直接输出视频帧序列给 ffmpeg 合成视频。CSS @keyframes 动画、animate-spin 这些 Tailwind 动画类,全部支持。
支持 backdrop-filter 和 blend modes。 毛玻璃效果?直接写 backdrop-filter: blur() 就行。
而且它不止能在 Node.js 上用。Cloudflare Workers 可以加载 WASM 构建,浏览器端也行,Rust 项目直接 crate 引用——四个部署目标,一个引擎。
// Cloudflare Workers 同步支持
import { render } from "takumi-js";
export default {
async fetch(req) {
const image = await render(
< div tw="w-full h-full flex items-center justify-center bg-black text-white">
< h1>Hello Workers< /h1>
< /div>,
{ width: 1200, height: 630 },
);
return new Response(image, {
headers: { "content-type": "image/png" },
});
},
};
🏃♂️ 跑题联想:Vercel 的 Satori 也做了类似的事
说到这个,我突然想起来 Vercel 的 Satori 也是干这个的——把 JSX 转成 SVG,不需要浏览器。但 Satori 有几个硬伤:只输出 SVG(你拿到的是一堆 <svg> 标签,还得再转一次才能变成 PNG),只支持 Flexbox,不支持 CSS 动画,而且只能在 Node/Edge Runtime 上跑。
Takumi 相当于把 Satori 没做完的事全做完了——而且是用 Rust 在底层重写了一遍。
用 Rust 写出这玩意儿,真的服。
老实说,这块的实现细节我没完全搞懂——它底层用了 taffy 做布局、parley 和 skrifa 做文字排版、resvg 处理 SVG,最后用自己写的管线做输出。但原理大概是这样,细节可能有出入——有懂的大佬欢迎指正。
谁在用?
看看这个列表就知道这玩意儿不是玩具:
- Dcard(台湾最大的社区平台)用来生成文章分享图
- TanStack 用它在文档里生成 OG 图
- Fumadocs 集成了 Takumi 作为默认渲染器
- Nuxt OG Image 把 Takumi 作为内置渲染器之一
- Luma 用它在活动分享页面上生成图片
而且它是 Vercel OSS Program 的成员项目——也就是说 Vercel 官方也在支持它。
上手体验
装一下试试,一行命令:
bun i takumi-js
然后直接写 JSX:
import { render } from "takumi-js";
import { writeFile } from "node:fs/promises";
const image = await render(
< div tw="w-full h-full flex items-center justify-center bg-gradient-to-b from-blue-100 to-red-50">
< h1 tw="text-6xl font-bold">Hello from Takumi< /h1>
< /div>,
{ width: 1200, height: 630 },
);
await writeFile("./output.png", image);
跑完之后你就会看到一张漂亮的渐变图。这就是 OG 图生成的全部代码了——没有 Docker,没有 Puppeteer,没有 Chrome。
如果你用的是 Next.js,替换就更简单了:
// 之前
// import { ImageResponse } from "next/og";
// 之后
import { ImageResponse } from "takumi-js/response";
export function GET() {
return new ImageResponse(
< div tw="...">
< h1>Hello< /h1>
< /div>,
{ width: 1200, height: 630 },
);
}
改一行导入,剩下全不变。
同类项目
如果你对这类"不需要浏览器就能生成图片"的工具感兴趣,还有几个值得看:
- Satori(Vercel): JSX→SVG,Takumi 的前辈,功能较基础
- @resvg/resvg(linebender): Rust 写的 SVG 渲染引擎,Takumi 的 SVG 输出背后就用了它
- Sharp:图片处理是老牌工具,但它不处理 HTML/CSS 渲染
觉得 Rust 生态有意思?我之前还写过一篇关于 Rust 工具链的文章,关注后回复「rust」可以看看。
总结
Takumi 做的事情很纯粹——把 OG 图生成从"开一个浏览器"降到了"调一个函数"。
300MB 的浏览器开销省了,冷启动延迟没了,还能部署到 Cloudflare Workers 上零成本运行。对于任何需要在服务端生成社交分享图的项目来说,这个工具都是降维打击。
装不装都行,看你自己。但你要是还在用 Puppeteer 生成 OG 图……嗯,你懂的。
本文使用 MGO 编辑并发布
关注"何三笔记",回复"mgo" 免费下载使用