Render JSX to images.
Skip the browser.
Headless Chromium needs ~300 MB and a cold start for one OG card. Takumi needs a function call.



The code is the design file.
Drop-in for next/og. The card is this source file, rendered.
export default function DemoCard() {
return (
<div tw="flex h-full w-full flex-col justify-between bg-[#16130f] p-14 text-white">
<div tw="flex items-center justify-between">
<span tw="text-2xl text-[#a8a29a]">takumi.kane.tw</span>
<span tw="h-10 w-10 bg-[#ff4d4d]" />
</div>
<h1
tw="text-7xl font-bold leading-tight"
style={{
backgroundClip: "text",
backgroundImage: "linear-gradient(110deg, #fff 60%, #ff4d4d)",
color: "transparent",
}}
>
This card is the code beside it.
</h1>
<div tw="flex items-center justify-between text-2xl text-[#a8a29a]">
<span>Rendered without a browser</span>
<span>1200 × 630</span>
</div>
</div>
);
}export default function DemoCard() {
return (
<div tw="flex h-full w-full flex-col justify-between bg-[#16130f] p-14 text-white">
<div tw="flex items-center justify-between">
<span tw="text-2xl text-[#a8a29a]">takumi.kane.tw</span>
<span tw="h-10 w-10 bg-[#ff4d4d]" />
</div>
<h1
tw="text-7xl font-bold leading-tight"
style={{
backgroundClip: "text",
backgroundImage: "linear-gradient(110deg, #fff 60%, #ff4d4d)",
color: "transparent",
}}
>
This card is the code beside it.
</h1>
<div tw="flex items-center justify-between text-2xl text-[#a8a29a]">
<span>Rendered without a browser</span>
<span>1200 × 630</span>
</div>
</div>
);
}
home-demo-card@2x.webp · 52 KB · rendered by bun example/twitter-images
One tree, sampled across time.
Pass a timestamp. PNG is t = 0. Animated WebP is the same tree over t.
@keyframes morph {
from { border-radius: 12%; transform: rotate(0deg) scale(1); }
50% { border-radius: 50%; transform: rotate(90deg) scale(0.72); }
to { border-radius: 12%; transform: rotate(180deg) scale(1); }
}







The CSS you write.
Not a tiny OG subset. Put the property back.
Layout
- display: grid
- float
- position: absolute
- calc()
- z-index
Selectors
- :is()
- :where()
- ::before
- ::after
Paint
- backdrop-filter
- mix-blend-mode
- conic-gradient()
- clip-path
- mask
- background-clip: text
Text
- WOFF2 fonts
- emoji
- RTL scripts
- multi-span inline
Motion
- @keyframes
- animation
- Tailwind animate-*
Native on Node. WASM on Workers and browsers. Crate for Rust.
People ship open graph cards, invoices, receipts, tickets, certificates, and paged PDF reports with it. One template renders to PNG, WebP, AVIF, JPEG, SVG, or PDF. No headless browser to install, keep warm, or pay for.
macOS · Linux · Windows · x64 · ARM64
匠
Render your first image.
bun i takumi-jsbun i takumi-jsLayout by taffy · text by parley & skrifa · SVG by resvg
MIT / Apache-2.0





