Renderers
Nuxt OG Image supports three rendering engines, each with different trade-offs.
Comparison
| Feature | Satori | Takumi | Browser |
|---|---|---|---|
| Speed | Fast | Fastest (2-10x) | Slow |
| Edge Runtime | ✅ | ✅ | ❌ |
| CSS Support | Partial | Limited | Full |
| Gradients | ✅ | ❌ | ✅ |
| Opacity | ✅ | ❌ | ✅ |
| Complex Flexbox | ✅ | Partial | ✅ |
| Shadows | Partial | ❌ | ✅ |
| Emoji | ✅ 6 families | ✅ COLR fonts | ✅ |
| Fonts | Google Fonts, local | WOFF2, variable | Any |
| Dependencies | Built-in | @takumi-rs/core | playwright |
| Best For | Default, most templates | High-throughput, simple templates | Complex designs, prerender only |
Environment Compatibility
| Environment | Satori | Takumi | Browser |
|---|---|---|---|
| Node.js | ✅ | ✅ @takumi-rs/core | ✅ playwright |
| Prerender / CI | ✅ | ✅ | ✅ Auto-installs |
| AWS Lambda | ✅ | ✅ | ❌ Binary too large |
| Vercel | ✅ | ✅ | ❌ |
| Vercel Edge | ✅ WASM | ✅ WASM | ❌ |
| Netlify | ✅ | ✅ | ❌ |
| Netlify Edge | ✅ WASM | ✅ WASM | ❌ |
| Cloudflare Workers | ✅ WASM | ✅ WASM | ❌ |
| Cloudflare Pages | ✅ WASM | ✅ WASM | ❌ |
| StackBlitz | ✅ WASM | ✅ WASM | ❌ |
Binding Types
Each renderer can use different bindings depending on the environment:
- node - Default Node.js binding, best performance
- wasm - WebAssembly binding for edge runtimes and workers
- wasm-fs - WebAssembly with filesystem access (dev environments like StackBlitz)
- false - Disabled
Provider Notes
AWS Lambda, Netlify, Vercel (Serverless)
- Browser unavailable (binary too large)
- Sharp unavailable (post-install script issues)
Vercel Edge, Netlify Edge, Cloudflare Pages
- Satori and Takumi use WASM automatically
- Browser and Sharp unavailable
Cloudflare Workers
- Satori and Takumi use WASM automatically
- Browser and Sharp unavailable
- Some limitations with custom fonts and images (issue #63)
Overriding Compatibility
You can override the default compatibility settings:
export default defineNuxtConfig({
ogImage: {
compatibility: {
// disable browser for prerendering (skips install in CI)
prerender: {
browser: false
},
// force WASM binding at runtime
runtime: {
resvg: 'wasm'
}
}
}
})
Component Naming Convention
OG Image components must include the renderer in their filename:
components/OgImage/
MyTemplate.satori.vue # Satori renderer
MyTemplate.takumi.vue # Takumi renderer
Screenshot.browser.vue # Browser renderer
This enables:
- Automatic renderer detection - no need to specify
rendererindefineOgImage() - Tree-shaking - unused renderer code is excluded from production builds
MyTemplate.satori.vue and MyTemplate.takumi.vue. When calling defineOgImage({ component: 'MyTemplate' }), the first registered variant is used. To select a specific renderer, use dot notation:defineOgImage({ component: 'MyTemplate.takumi' })
'MyTemplateTakumi'.Choosing a Renderer
The renderer is determined by the component filename suffix — there is no global defaults.renderer config.
Use Satori (Default)
Satori works for most use cases. Create your component with a .satori.vue suffix:
components/OgImage/MyTemplate.satori.vue
Use Takumi
Choose Takumi when you need maximum performance with simple templates that use solid colors:
components/OgImage/MyTemplate.takumi.vue
Use Browser
Choose Browser when you need full CSS support and are prerendering all images at build time:
components/OgImage/MyTemplate.browser.vue
Zero Runtime Mode
If you're prerendering all OG images at build time, enable Zero Runtime mode to remove all renderer code from your production bundle (81% smaller Nitro output).
export default defineNuxtConfig({
ogImage: {
zeroRuntime: true
}
})
This works with any renderer and is ideal when your OG images don't change dynamically.