Home / Compare / Satori / @vercel/og

Satori / @vercel/og Alternative

Satori renders a subset of CSS. HTML to Image renders the web: full CSS, JavaScript, web fonts and emoji in real Chrome, from any framework.

Disclosure: we built HTML to Image. Satori is clever engineering with deliberate trade-offs; this page is about what happens when your design outgrows them.

Factor Satori / @vercel/og HTML to Image
Cost to startFree (open source)$0 to start — 25 renders/month free
Infrastructure to runRuns inside your functions or edge runtimeNone — hosted API
Ongoing maintenanceFont loading, emoji setup, CSS workaroundsNone
Rendering engineCustom renderer — a subset of CSS, flexbox onlyHeadless Chrome — full CSS
JavaScript executionNo — static JSX/HTML onlyYes
Scaling & concurrencyScales with your functionsHandled by the API
Named templatesNo25
CDN-hosted outputNo — streams from your function each requestYes — every render returns a CDN URL
Best forsimple OG cards inside a Next.js/Vercel appfull-fidelity images from real HTML, in any framework

Should you switch?

Stay with @vercel/og when your card genuinely fits the subset: flexbox layout, a couple of fonts you load yourself, no emoji surprises, and you are on Vercel anyway. Within those lines Satori is fast and free, and there is nothing to fix.

Switch to HTML to Image when the design outgrows the renderer. The failure modes are predictable and we have documented them: CSS grid, absolute positioning quirks and background limitations that silently render wrong, and emoji that come out as blank boxes without per-glyph font plumbing. In real Chrome those problems do not exist — the markup that works on your site works in the image, JavaScript included. And because every render returns a stored CDN URL, you render each image once instead of re-rendering on every crawler hit. The migration pattern is in our guide to dynamic OG images in Next.js without @vercel/og.

Where HTML to Image wins

The whole CSS spec, not a subset. Grid, floats, filters, blend modes, pseudo-elements, web fonts by URL and JavaScript-driven content — if Chrome renders it, the image has it. No mental checklist of what Satori supports before you touch a design.

Emoji and international text that just work. No glyph APIs, no font subsetting, no broken flag sequences. Chrome ships the same emoji and shaping behaviour as every browser your users have.

Framework-independent with hosted output. Works from Rails, Laravel, WordPress or a static site generator — see our guides for Astro, Hugo and Eleventy and Nuxt — plus 25 named templates when you would rather skip the markup entirely.

Where Satori / @vercel/og wins

Latency and price inside its lane. Rendering at the edge in tens of milliseconds with no external call and no per-render fee is a real advantage for simple cards generated on the fly on Vercel.

JSX ergonomics for React teams. Defining an OG card as a React component inside the repo, versioned with the code, is a pleasant workflow while the design stays inside the subset.

The same card, both ways

jsx
// @vercel/og — JSX in, PNG out, within Satori's CSS subset
import { ImageResponse } from '@vercel/og';

export default function handler() {
  return new ImageResponse(
    (
      <div style={{ display: 'flex', fontSize: 64 }}>
        Hello  {/* flexbox only, no JS, emoji need setup */}
      </div>
    ),
    { width: 1200, height: 630 },
  );
}
bash
# HTML to Image — real HTML, real Chrome, full CSS
curl -X POST https://app.html2img.com/api/html \
  -H 'X-API-Key: your-key-here' \
  -H 'Content-Type: application/json' \
  -d '{"html":"<h1>Hello 👋</h1>","css":"h1{font-size:64px}",
       "width":1200,"height":630}'
# Response includes a CDN-hosted URL

The migration is usually a simplification: your JSX card becomes plain HTML and CSS with no subset rules, sent to the HTML endpoint. Render at publish time rather than request time, store the returned CDN URL in front matter or your database, and the OG route handler disappears entirely.

Total cost of ownership

Satori is free per render but you pay in constraints and workarounds: font files fetched and passed manually, emoji glyph services, designs re-engineered to flexbox, and debugging output that almost matches the browser. The moment a design review says "why does this look different from the site?", you are spending engineer time that costs more than $9 a month. If your cards are simple and stay simple, the free option is genuinely fine — that honesty cuts both ways.

Further reading

FAQ

What exactly can't Satori render?

Satori implements a deliberate subset of CSS: flexbox layout only (no grid, no floats), no JavaScript, limited background and filter support, and every element needs display: flex if it has multiple children. Real-world designs hit these walls fast — we keep a detailed list in our article on Satori's CSS limits. HTML to Image renders in actual Chrome, so if it works on a web page it works in the image.

Why do emoji break in @vercel/og?

Satori has no built-in emoji font, so emoji render as blank boxes unless you wire up an external glyph source per emoji — and combined sequences like flags and skin tones are patchy even then. We wrote up the mechanics and the fix in "Why @vercel/og fails on emoji". In headless Chrome, emoji are just text: they render correctly with zero setup.

When is @vercel/og the right choice?

When your design fits the subset and you are already on Vercel. For a simple OG card — solid background, a heading, a logo — Satori is genuinely fast, renders at the edge, and costs nothing extra on your existing plan. If your card never hits the CSS limits or the emoji problem, there is no urgent reason to switch.

Do I have to leave Vercel or Next.js to use HTML to Image?

No. You call the API from wherever you run — a Next.js route handler, a build step, or your CMS. Our guide to dynamic OG images in Next.js without @vercel/og shows the pattern: render once, store the CDN URL in your front matter or database, and stop paying a render on every crawler hit.

Render the design you actually want

The free tier covers 25 renders a month with no credit card. Send the markup Satori couldn't handle and see it come back correct.

Templates you can render with HTML to Image

Or skip the markup entirely. Twenty-five pre-built designs — including OG image templates — rendered from JSON in real Chrome.

See every template in the gallery

More comparisons