March 29, 2026 · 10 min read

OGPeek vs Satori: API vs Building Your Own OG Image Pipeline

Satori is the open-source library that powers Vercel's OG image generation. It converts JSX to SVG, and with resvg, you can turn that SVG into a PNG. It's powerful. It's also a lot of work to self-host. Here's when to use Satori directly vs when OGPeek's hosted API makes more sense.

What is Satori?

Satori is Vercel's open-source library (vercel/satori on GitHub) that converts a JSX-like virtual DOM tree into an SVG string. It supports a subset of CSS Flexbox, custom fonts (via ArrayBuffer), and basic text layout. It does not output PNG—you need a second library like @resvg/resvg-js or Sharp to rasterize the SVG.

Satori is what powers @vercel/og under the hood. But you can use Satori directly in any Node.js project, any serverless function, or any edge runtime. It's framework-agnostic at the library level.

What You Actually Need to Build

Using Satori to generate OG images in production requires more than npm install satori. Here's the full stack you need to assemble:

  1. Satori — JSX to SVG conversion
  2. resvg-js or Sharp — SVG to PNG rasterization
  3. Font loading — fetch and cache .ttf/.woff2 files as ArrayBuffers
  4. HTTP server — Express, Fastify, Hono, or a serverless function
  5. Caching layer — CDN or Redis to avoid re-rendering identical images
  6. Error handling — graceful fallbacks for invalid inputs
  7. Hosting — AWS Lambda, Cloud Functions, Fly.io, or similar
  8. Monitoring — uptime checks, error tracking

Each of these is a real engineering task. Font loading alone is tricky—Satori requires fonts as ArrayBuffers, and Google Fonts doesn't serve raw .ttf files at their CSS URLs. You need to parse the CSS response, extract the font URL, fetch the binary, and cache it.

Minimum Viable Satori Setup

// server.js — ~80 lines before you add caching, error handling, or templates
import satori from 'satori';
import { Resvg } from '@resvg/resvg-js';
import { readFileSync } from 'fs';

const font = readFileSync('./Inter-Bold.ttf');

async function generateOG(title, subtitle) {
  const svg = await satori(
    {
      type: 'div',
      props: {
        style: {
          width: '100%', height: '100%', display: 'flex',
          flexDirection: 'column', justifyContent: 'center',
          padding: '80px', background: '#0F0F12',
        },
        children: [
          { type: 'div', props: {
            style: { fontSize: 64, fontWeight: 700, color: '#FFF' },
            children: title
          }},
          { type: 'div', props: {
            style: { fontSize: 28, color: '#9B9BA7', marginTop: 20 },
            children: subtitle
          }},
        ],
      },
    },
    {
      width: 1200, height: 630,
      fonts: [{ name: 'Inter', data: font, weight: 700, style: 'normal' }],
    }
  );

  const resvg = new Resvg(svg, { fitTo: { mode: 'width', value: 1200 } });
  return resvg.render().asPng();
}

That's the bare minimum. No templates, no theme system, no caching, no API key management, no usage tracking. Every feature you'd want in production is additional code you write and maintain.

The Same Image with OGPeek

# One line. No server. No dependencies. No font files.
curl "https://todd-agent-prod.web.app/api/v1/og?\
title=Ship+Faster+with+AI&\
subtitle=A+developer+guide&\
template=gradient&\
theme=midnight&\
brandColor=%23FF7A00" --output og.png

Or as a meta tag in your HTML:

<meta property="og:image" content="https://todd-agent-prod.web.app/api/v1/og?title=Your+Title&template=editorial&theme=dark" />

Comparison Table

Factor Satori (DIY) OGPeek (API)
Setup time 4–8 hours (with hosting) 2 minutes
Design control Full (write any JSX layout) 7 templates + customization params
Font support BYO fonts (ArrayBuffer loading) Built-in premium fonts
Hosting You manage (Lambda, Cloud Functions, etc.) Fully hosted
Caching You build (CDN, Redis, etc.) Built-in CDN caching
Cost for 5,000 images/mo $5–20/mo (hosting + compute) $9/mo (Starter plan)
Cost for 50 images/day $0–5/mo (minimal hosting) $0 (free tier)
Maintenance Ongoing (dependency updates, font management) Zero
Framework requirement Node.js (or Deno/Bun with compat) None — any language, any platform
Production readiness You build error handling, rate limiting, etc. Production-ready out of the box

When Satori Makes Sense

Satori is the right choice when:

When OGPeek Makes Sense

OGPeek is the right choice when:

The real comparison isn't price—it's time. If your hourly rate is $50 and Satori setup takes 6 hours, that's $300 of your time before you generate a single image. OGPeek's Starter plan is $9/month—that's 33 months of the API for the cost of one DIY setup.

The Hybrid Approach

Some teams use both. Start with OGPeek for rapid prototyping and initial launch. If you later need custom layouts that templates can't handle, migrate to Satori for those specific pages while keeping OGPeek for the rest. OGPeek's API is just a URL—easy to swap out page by page.

Bottom Line

Satori is a remarkable open-source library. If you enjoy infrastructure work and need unlimited design flexibility, it's the right tool. But for most developers who just need great-looking OG images without the engineering overhead, OGPeek gets you there in 2 minutes instead of 2 days.

Try OGPeek Free

50 images/day, no credit card required. See if the templates work for your use case before writing a single line of infrastructure code.

Get Started →