Universal SVG to PNG renderer that works with international text, emojis, and complex fonts.
- Converts SVG to PNG using WASM (works in Cloudflare Workers)
- Handles CJK characters, Arabic, Hebrew, emojis, basically any Unicode
- All fonts bundled locally, no network requests
- Text shaping with harfbuzzjs (GSUB, ligatures, RTL)
- Fallback font system so text never disappears
- No server dependencies, no Canvas API
yarn add rasterize-wasmimport { UniversalSVGRenderer } from 'rasterize-wasm';
const renderer = new UniversalSVGRenderer();
// from SVG string
const pngBuffer = await renderer.render(svgString);
// to file
await renderer.render(svgString, { format: 'file', path: 'output.png' });
// to base64
const base64 = await renderer.render(svgString, { format: 'base64', dataURL: true });| SVG Input | PNG Output |
|---|---|
![]() |
|
![]() |
|
![]() |
// basic text
const svg = `<svg width="200" height="100">
<text x="10" y="50" font-size="20">Hello 世界! 🌍</text>
</svg>`;
// custom fallback font
const renderer = new UniversalSVGRenderer({
fallbackFont: 'Noto+Sans'
});
// multiple outputs at once
const results = await renderer.render(svg, {
buffer: true,
base64: true,
file: 'output.png'
});- extracts text from SVG
- loads embedded fonts or bundled Noto Sans fallbacks
- shapes text with harfbuzzjs (handles RTL, ligatures, GSUB features)
- converts shaped glyphs to SVG paths
- replaces original text elements with paths
- renders final SVG to PNG with resvg-wasm
Every other solution either:
- doesn't handle international text
- requires system fonts
- needs Canvas API
- breaks on emojis, especially compound emojis (ZWJ sequences, flags, keycaps)
- doesn't work in Workers
This one actually works.
WASM is bundled locally. For Workers, pass the WASM buffer:
import wasmBuffer from './node_modules/rasterize-wasm/wasm/resvg.wasm';
import { UniversalSVGRenderer } from 'rasterize-wasm';
export default {
async fetch(request, env) {
const renderer = new UniversalSVGRenderer();
const svg = await request.text();
// Pass WASM buffer through render options
const png = await renderer.render(svg, {
buffer: true,
wasmBuffer: wasmBuffer
});
return new Response(png, {
headers: { 'Content-Type': 'image/png' }
});
}
}Make sure your wrangler.toml has:
[build]
upload.format = "modules"yarn exampleCheck examples/usage.js for more patterns.


