Use Takumi in Cloudflare Workers
Integrate Takumi with Cloudflare Workers image generation at the edge.
Takumi has first-class support for Cloudflare Workers, allowing you to generate images dynamically at the edge without any cost.
Thanks to awesome performance optimizations, Takumi works within Workers' free plan CPU time constraints. Here's a deployed example: takumi-on-workers-example.kane.tw?name=your-name.
Create a New Wrangler Project
First, create a new Cloudflare Workers project using Wrangler:
npm create cloudflare@latest og-image-worker
Navigate to your project directory:
cd og-image-worker
Install Dependencies
Install Takumi packages and Wrangler:
npm install @takumi-rs/wasm @takumi-rs/helpers
Configure Wrangler
If you are using external fonts or images, add rules
configuration to your wrangler.jsonc
to handle import statements.
The verified minimum compatibility date is 2025-08-03
. If you are encountering errors related to WASM module initialization, please check your compatibility date.
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "og-image-worker",
"main": "src/index.ts",
"compatibility_date": "2025-08-03",
"rules": [
{
"type": "Data",
"globs": ["**/*.ttf", "**/*.woff", "**/*.woff2"],
"fallthrough": true
}
]
}
Initialize WASM Module
Import the WASM like this and Wrangler will handle the initialization part for you. Make sure to call initSync
before initializing the Renderer
instance.
import { initSync, Renderer } from "@takumi-rs/wasm";
import module from "@takumi-rs/wasm/takumi_wasm_bg.wasm";
initSync({ module });
const renderer = new Renderer();
Load Static Assets
To maintain the minimal size of the WASM file, we don't provide default embedded fonts like Geist or Geist Mono. You need to load them manually.
Load fonts and persistent images when your worker starts.
import { initSync, Renderer } from "@takumi-rs/wasm";
import module from "@takumi-rs/wasm/takumi_wasm_bg.wasm";
import medium from "../../assets/fonts/noto-sans/noto-sans-v39-latin-500.woff2";
import bold from "../../assets/fonts/noto-sans/noto-sans-v39-latin-700.woff2";
initSync({ module });
const renderer = new Renderer();
renderer.loadFont(new Uint8Array(medium));
renderer.loadFontWithInfo({
data: new Uint8Array(bold),
name: "Noto Sans",
weight: 700,
style: "normal",
});
Handle Dynamic Assets
Cloudflare Workers does not support top-level await, so you need to initialize assets in the fetch handler.
// Store in base64 data URI
let logoUrl: string;
export default {
async fetch(request: Request) {
logoUrl ??= await fetchLogo();
},
}
Deploy
Deploy your worker using Wrangler:
npm run deploy
You should now have a working Takumi worker. Check out the full Cloudflare Workers example here to see a working example.
If you encounter any issues, please file an issue here.