Skip to main content

Takumi Engine

Generate images with the Takumi rendering engine for more formats and a smaller bundle.

Overview

SvelteKit OG ships two rendering engines. The default ImageResponse uses Satori (HTML → SVG → PNG). As an alternative, you can render with Takumi — a Rust engine (native on Node, WebAssembly on the edge) that renders HTML and Svelte components directly to images.

Reach for Takumi when you want:

  • More output formatspng, jpeg, webp, ico, raw, and svg.
  • A built-in font — text renders out of the box, no font fetch required.
  • A smaller install — the Takumi WebAssembly is loaded from takumi-js, so nothing extra is bundled into @ethercorps/sveltekit-og.

Installation

The Takumi engine lives behind a separate entry point and takumi-js is an optional peer dependency — install it alongside the package. Apps that only use Satori don't need it.

		pnpm add @ethercorps/sveltekit-og takumi-js
	

Guide

Import ImageResponse from the /takumi entry point. The constructor takes the same shape as the Satori one — an HTML string or a Svelte component, then options, then component props.

Raw HTML

routes/images/takumi.png/+server.ts
		import { ImageResponse } from '@ethercorps/sveltekit-og/takumi';
import type { RequestHandler } from '@sveltejs/kit';
 
const template = `
<div style="display: flex; width: 100%; height: 100%; align-items: center; justify-content: center; background: #101011;">
	<h1 style="color: gray; font-size: 80px;">Hello Takumi</h1>
</div>
`;
 
export const GET: RequestHandler = async () => {
	return new ImageResponse(template, { width: 1200, height: 630 });
};
	

Svelte Component

Pass the component as the first argument and its props as the third — exactly like the Satori engine. Use <svelte:options css="injected" /> so component styles are inlined into the SSR output.

routes/images/takumi-component.png/+server.ts
		import { ImageResponse } from '@ethercorps/sveltekit-og/takumi';
import type { RequestHandler } from '@sveltejs/kit';
import OG from '$lib/components/og/simple.svelte';
 
export const GET: RequestHandler = async () => {
	return new ImageResponse(OG, { width: 1200, height: 630 }, { title: 'Hello Takumi' });
};
	

Output Formats

Set format to control the encoding. quality (0–100) applies to the lossy formats (jpeg, webp).

		// WebP at 80% quality
new ImageResponse(template, { format: 'webp', quality: 80 });
 
// JPEG
new ImageResponse(template, { format: 'jpeg', quality: 90 });
 
// Vector SVG
new ImageResponse(template, { format: 'svg' });
	
Format Content-Type
png (default) image/png
jpeg image/jpeg
webp image/webp
ico image/x-icon
svg image/svg+xml
raw application/octet-stream

Fonts

Takumi ships a built-in sans-serif, so the examples above work with no fonts configured. To use your own, pass font instances to the fonts option.

+server.ts
		import { ImageResponse, GoogleFont, CustomFont } from '@ethercorps/sveltekit-og/takumi';
import { read } from '$app/server';
import RegularFont from '$lib/assets/MyFont-Regular.ttf?url';
 
export const GET = async () => {
	return new ImageResponse(
		`<div style="display:flex; font-family: 'Inter'">Hello World</div>`,
		{
			width: 1200,
			height: 630,
			fonts: [
				new GoogleFont('Inter', { weight: 400 }),
				new CustomFont('My Font', () => read(RegularFont).arrayBuffer(), { weight: 700 })
			]
		}
	);
};
	

You can also pass a raw Takumi font descriptor — an object with name, data (bytes or a loader), and optional weight / style:

		new ImageResponse(template, {
	fonts: [
		{
			name: 'Inter',
			data: () => fetch('https://example.com/inter.woff2').then((r) => r.arrayBuffer()),
			weight: 400
		}
	]
});
	

Emoji

Emoji are rendered from a provider, controlled with the emoji option (defaults to twemoji). Set it to "from-font" to source emoji glyphs from your loaded fonts instead.

		new ImageResponse(`<div style="display:flex">Ship it 🚀</div>`, { emoji: 'noto' });
	

Options Reference

Everything the constructor accepts, passed as the second argument.

Option Type Default Description
width number 1200 Image width in pixels.
height number 630 Image height in pixels.
format TakumiFormat 'png' Output format — see Output Formats.
quality number 0100, applies to lossy jpeg / webp.
fonts TakumiFontInput[] built-in font Fonts to register — see Fonts.
stylesheets string[] Extra CSS stylesheets applied before rendering.
emoji EmojiType | 'from-font' 'twemoji' Emoji provider — see Emoji.
debug boolean false Log render timing and diagnostics.
status number 200 HTTP status code of the Response.
statusText string 'Success' HTTP status text of the Response.
headers Record<string, string> Extra response headers (merged with the Content-Type).

Next Steps

  • Satori vs Takumi: The default Svelte and Raw HTML guides cover the Satori engine. The API is the same — only the import and supported formats differ.
  • Fonts: The Fonts guide explains GoogleFont and CustomFont in detail.
  • Local Assets: To include local images in your images, see Local Assets.