vercel/satori is a Image Tools project on GitHub, written primarily in TypeScript. It has 13.7k stars. Enlightened library to convert HTML and CSS to SVG
Snapshot summary built from the project's own GitHub metadata — there's no written TopGit review yet. The page will update automatically when a full review is published.
WHY NO REVIEW YET
TopGit writes full reviews for the most-starred, most-requested repositories. This page is a snapshot until then — see the READ ME tab for the original README in full.
Satori: Enlightened library to convert HTML and CSS to SVG.
Note
To use Satori in your project to generate PNG images like Open Graph images and social cards, check out our announcement and Vercel’s Open Graph Image Generation →
To use it in Next.js, take a look at the Next.js Open Graph Image Generation template →
Overview
Satori supports the JSX syntax, which makes it very straightforward to use. Here’s an overview of the basic usage:
// api.jsx
import satori from 'satori'
const svg = await satori(
<div style={{ color: 'black' }}>hello, world</div>,
{
width: 600,
height: 400,
fonts: [
{
name: 'Roboto',
// Use `fs` (Node.js only) or `fetch` to read the font as Buffer/ArrayBuffer and provide `data` here.
data: robotoArrayBuffer,
weight: 400,
style: 'normal',
},
],
},
)
Satori will render the element into a 600×400 SVG, and return the SVG string:
Under the hood, it handles layout calculation, font, typography and more, to generate a SVG that matches the exact same HTML and CSS in a browser.
Documentation
JSX
Satori only accepts JSX elements that are pure and stateless. You can use a subset of HTML
elements (see section below), or custom React components, but React APIs such as useState, useEffect, dangerouslySetInnerHTML are not supported.
Experimental: builtin JSX support
Satori has an experimental JSX runtime that you can use without having to install React. You can enable it on a per-file basis with @jsxImportSource pragmas. In the future, it will autocomplete only the subset of HTML elements and CSS properties that Satori supports for better type-safety.
If you don't have JSX transpiler enabled, you can simply pass React-elements-like objects that have type, props.children and props.style (and other properties too) directly:
Satori supports a limited subset of HTML and CSS features, due to its special use cases. In general, only these static and visible elements and properties that are implemented.
For example, the <input> HTML element, the cursor CSS property are not in consideration. And you can't use <style> tags or external resources via <link> or <script>.
Also, Satori does not guarantee that the SVG will 100% match the browser-rendered HTML output since Satori implements its own layout engine based on the SVG 1.1 spec.
You can find the list of supported HTML elements and their preset styles here.
Images
You can use <img> to embed images. However, width, and height attributes are recommended to set:
When using background-image, the image will be stretched to fit the element by default if you don't specify the size.
If you want to render the generated SVG to another image format such as PNG, it would be better to use base64 encoded image data (or buffer) directly as props.src so no extra I/O is needed in Satori:
Satori uses the same Flexbox layout engine as React Native, and it’s not a complete CSS implementation. However, it supports a subset of the spec that covers most common CSS features:
Property
Property Expanded
Supported Values
Example
CSS Variables
Supported, including --var-name declaration and var(--var-name) usage with fallback values
Example
display
flex, contents, none, default to flex
position
relative, static and absolute, default to relative
color
Supported
margin
marginTop
Supported
marginRight
Supported
marginBottom
Supported
marginLeft
Supported
Position
top
Supported
right
Supported
bottom
Supported
left
Supported
Size
width
Supported
height
Supported
Min & max size
minWidth
Supported except for min-content, max-content and fit-content
minHeight
Supported except for min-content, max-content and fit-content
maxWidth
Supported except for min-content, max-content and fit-content
maxHeight
Supported except for min-content, max-content and fit-content
border
Width (borderWidth, borderTopWidth, ...)
Supported
Style (borderStyle, borderTopStyle, ...)
solid and dashed, default to solid
Color (borderColor, borderTopColor, ...)
Supported
Shorthand (border, borderTop, ...)
Supported, i.e. 1px solid gray
borderRadius
borderTopLeftRadius
Supported
borderTopRightRadius
Supported
borderBottomLeftRadius
Supported
borderBottomRightRadius
Supported
Shorthand
Supported, i.e. 5px, 50% / 5px
Flex
flexDirection
column, row, row-reverse, column-reverse, default to row
flexWrap
wrap, nowrap, wrap-reverse, default to nowrap
flexGrow
Supported
flexShrink
Supported
flexBasis
Supported except for auto
alignItems
stretch, center, flex-start, flex-end, baseline, normal, default to stretch
alignContent
Supported
alignSelf
Supported
justifyContent
Supported
gap
Supported
Font
fontFamily
Supported
fontSize
Supported
fontWeight
Supported
fontStyle
Supported
Text
tabSize
Supported
textAlign
start, end, left, right, center, justify, default to start
textIndent
Supported, including negative values (hanging indent)
textTransform
none, lowercase, uppercase, capitalize, defaults to none
textOverflow
clip, ellipsis, defaults to clip
textDecoration
Support line types underline and line-through, and styles dotted, dashed, double, solid
Example
textShadow
Supported
lineHeight
Supported
letterSpacing
Supported
whiteSpace
normal, pre, pre-wrap, pre-line, nowrap, defaults to normal
wordBreak
normal, break-all, break-word, keep-all, defaults to normal
textWrap
wrap, balance, defaults to wrap
Background
backgroundColor
Supported, single value
backgroundImage
linear-gradient, repeating-linear-gradient, radial-gradient, repeating-radial-gradient, url, single value
backgroundPosition
Support single value
backgroundSize
Support cover, contain, auto, and two-value sizes i.e. 10px 20%
Example
backgroundClip
border-box, text
backgroundRepeat
repeat, repeat-x, repeat-y, no-repeat, defaults to repeat
transform
Translate (translate, translateX, translateY)
Supported
Rotate
Supported
Scale (scale, scaleX, scaleY)
Supported
Skew (skew, skewX, skewY)
Supported
transformOrigin
Support one-value and two-value syntax (both relative and absolute values)
objectFit
Supported
Example
objectPosition
Supports keywords (top, bottom, left, right, center), percentages (e.g., 25% 75%), lengths (e.g., 10px 20px), and mixed values (e.g., left 20%). Defaults to center (50% 50%).
repeat, repeat-x, repeat-y, no-repeat, defaults to repeat
Example
WebkitTextStroke
WebkitTextStrokeWidth
Supported
WebkitTextStrokeColor
Supported
Note:
Three-dimensional transforms are not supported.
There is no z-index support in SVG. Elements that come later in the document will be painted on top.
calc isn't supported.
currentColor support is only available for the color property.
CSS variables (custom properties) are supported, including inheritance, fallback values, and nested variables.
Language and Typography
Advanced typography features such as kerning, ligatures and other OpenType features are not currently supported.
RTL languages are not supported either.
Fonts
Satori currently supports three font formats: TTF, OTF and WOFF. Note that WOFF2 is not supported at the moment. You must specify the font if any text is rendered with Satori, and pass the font data as ArrayBuffer (web) or Buffer (Node.js):
Multiple fonts can be passed to Satori and used in fontFamily.
[!TIP]
We recommend you define global fonts instead of creating a new object and pass it to satori for better performance, if your fonts do not change. Read it for more detail
Emojis
To render custom images for specific graphemes, you can use graphemeImages option to map the grapheme to an image source:
The image will be resized to the current font-size (both width and height) as a square.
Locales
Satori supports rendering text in different locales. You can specify the supported locales via the lang attribute:
await satori(
<div lang="ja-JP">骨</div>
)
Same characters can be rendered differently in different locales, you can specify the locale when necessary to force it to render with a specific font and locale. Check out this example to learn more.
Supported locales are exported as the Locale enum type.
Dynamically Load Emojis and Fonts
Satori supports dynamically loading emoji images (grapheme pictures) and fonts. The loadAdditionalAsset function will be called when a text segment is rendered but missing the image or font:
await satori(
<div>👋 你好</div>,
{
// `code` will be the detected language code, `emoji` if it's an Emoji, or `unknown` if not able to tell.
// `segment` will be the content to render.
loadAdditionalAsset: async (code: string, segment: string) => {
if (code === 'emoji') {
// if segment is an emoji
return `data:image/svg+xml;base64,...`
}
// if segment is normal text
return loadFontFromSystem(code)
}
}
)
Runtime Support
Satori can be directly used in browser, Node.js (>= 16), and Web Workers. It bundles its underlying WASM dependencies as base64-encoded strings and loads them at runtime.
If there is a limitation on dynamically loading WASM (e.g. Cloudflare Workers), you can use the Standalone Build which is mentioned below.
Standalone Build of Satori
Satori's standalone build doesn't include Yoga's WASM binary by default, and you need to load it manually before using Satori.
First, you need to download the yoga.wasm binary from Satori build and provide it yourself. Let's use fetch to load it directly from the CDN as an example:
import satori, { init } from 'satori/standalone'
const res = await fetch('https://unpkg.com/satori/yoga.wasm')
const yogaWasm = await res.arrayBuffer()
await init(yogaWasm)
// Now you can use satori as usual
const svg = await satori(...)
Of course, you can also load the yoga.wasm file from your local disk via fs.readFile in Node.js or other methods.
Font Embedding
By default, Satori renders the text as <path> in SVG, instead of <text>. That means it embeds the font path data as inlined information, so succeeding processes (e.g. render the SVG on another platform) don’t need to deal with font files anymore.
You can turn off this behavior by setting embedFont to false, and Satori will use <text> instead:
Set pointScaleFactor to control how layout values are rounded to the pixel grid. This parameter is passed directly to Yoga’s pointScaleFactor and improves rendering precision on high-DPI displays.
How does vercel/satori compare to other Image Tools projects?
vercel/satori is tracked by TopGit in the Image Tools category, with 13.7k GitHub stars and written in TypeScript. Browse the Image Tools topic page on TopGit to compare it against similar projects by stars and activity.
How many stars does vercel/satori have?
vercel/satori has 13.7k GitHub stars — refresh the page for the live number, or check github.com/vercel/satori. TopGit mirrors GitHub's count but does not claim minute-by-minute accuracy.
Is vercel/satori open source?
Yes — vercel/satori ships under the MPL-2.0 license, which makes its source code freely readable (and, depending on license terms, forkable and reusable). Source: github.com/vercel/satori.
What else is in the Image Tools space?
vercel/satori is tracked by TopGit under the Image Tools category, alongside 9 GitHub-tagged topics. Trending and Topics pages list peer repositories of comparable stars and language.
What is vercel/satori?
vercel/satori (vercel/satori) is a TypeScript project on GitHub. From the project's own README: Enlightened library to convert HTML and CSS to SVG
Where can I see vercel/satori in action?
The project maintains a homepage at https://og-playground.vercel.app. The README tab on this page also usually contains screenshots and a quickstart.
Where do I read more about vercel/satori?
This TopGit page is a snapshot — the READ ME tab shows the project's own README content (links stripped, images preserved). The GitHub repository at github.com/vercel/satori is the definitive source.
Read full README in the tab above.
Still deciding about satori?
One click hands the question to an AI along with this page — see what it says about satori.