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.
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





