A dynamic Open Graph image API that runs on Cloudflare's global edge, ships in 3 lines, and costs nothing for the first 50 images a day. No @vercel/og, no Next.js, no Vercel account.
| Feature | og.hjlabs.in | @vercel/og |
|---|---|---|
| Requires Next.js | No | Yes (Edge runtime) |
| Hosting required | None — public URL | Vercel or self-host |
| Free tier | 50 images/day, no signup | Tied to Vercel free plan |
| Setup time | 30 seconds (paste a URL) | 15-30 minutes (npm + routes) |
| Templates included | 6 (default, blog, product, social, minimal, nature) | Build from scratch (JSX) |
| Custom HTML/JSX | Templates + color overrides | Full JSX |
| Edge network | Cloudflare (320+ cities) | Vercel Edge |
| Cold start (p95) | ~1.5s warm, ~2s cold | ~1-3s on Edge |
| Works with Astro / Nuxt / SvelteKit / Remix / WordPress / static HTML | Yes | Next.js only |
| Output format | SVG (renderable to PNG) | PNG |
| Paid tier | $12/mo Pro — 10K calls/mo | Vercel function pricing |
TL;DR. Pick @vercel/og if you're already on Next.js + Vercel and need full JSX freedom. Pick og.hjlabs.in if you want a zero-setup URL you can drop into any framework, with templates that already look good.
Replace your Next.js API route with a single URL in your metadata config.
// app/api/og/route.tsx
import { ImageResponse } from '@vercel/og';
export const runtime = 'edge';
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const title = searchParams.get('title') ?? 'Untitled';
return new ImageResponse(
(<div style={{ fontSize: 64, color: 'white', background: '#111', /* ... */ }}>
{title}
</div>),
{ width: 1200, height: 630 }
);
}
// app/layout.tsx
export const metadata = {
openGraph: { images: ['/api/og?title=My+Post'] }
};
// app/layout.tsx
export const metadata = {
openGraph: {
images: ['https://og.hjlabs.in/api/og?title=My+Post&template=blog&brand=mysite.com']
}
};
// Done. Delete app/api/og/route.tsx.
No npm install, no Edge function deploy, no cold start tax on every Next.js build. The image is cached at Cloudflare's edge after first generation.
<meta property="og:image"
content="https://og.hjlabs.in/api/og?title=My+Page&template=default&brand=example.com">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image"
content="https://og.hjlabs.in/api/og?title=My+Page&template=default&brand=example.com">
---
const ogImage = `https://og.hjlabs.in/api/og?title=${encodeURIComponent(title)}&template=blog`;
---
<meta property="og:image" content={ogImage} />
curl -o preview.svg \
"https://og.hjlabs.in/api/og?title=Hello+World&subtitle=Shipped+in+30+seconds&template=blog&brand=hjlabs.in"
The engine powering @vercel/og. You self-host the rendering — full control but you operate the infra.
Polished template editor, paid from $49/mo. Best if non-devs are designing templates.
Hosted OG generation from $9/mo. Closed-source, similar to og.hjlabs.in but no free tier.
Template-based image generation from $19/mo. Strong template marketplace.
The Cloudflare Worker port of Satori. og.hjlabs.in is built on this under the hood — we just give you the hosted URL.
Vercel's first OG image service. No longer maintained; replaced by @vercel/og library.
@vercel/og.For everything else — blog posts, product pages, social campaigns, indie SaaS landing pages — the dynamic URL approach is faster to ship and cheaper to operate.
Vercel OG is tightly coupled to the Next.js Edge runtime and works best when deployed on Vercel. Developers on Astro, Nuxt, SvelteKit, Remix, plain HTML, WordPress, or non-Vercel hosts often want a framework-agnostic alternative they can hit as a simple URL.
Yes. Free tier covers 50 OG image generations per day per IP with no signup and no watermark. Pro ($12/mo) lifts the limit to 10K API calls/month with priority generation.
Both use the same rendering engine — Satori. Vercel OG bundles it for the Next.js Edge runtime. og.hjlabs.in bundles workers-og for Cloudflare Workers and exposes it as a public REST endpoint.
Yes. Drop the URL straight into your metadata.openGraph.images config or your <head> meta tags. You skip the Next.js Edge cold-start and the Vercel function invocation cost.
Yes. Cloudflare caches the response globally after the first request. Identical query strings serve in under 50ms from the closest edge.