Skip to content

bensblueprints/og-image-studio

Repository files navigation

🖼️ OG Image Studio

MIT License Node 20+ Self--hosted

Your self-hosted Bannerbear. Design social-card templates visually, then render them programmatically — dynamic OG images, X cards, podcast episode art, quote cards — from a single GET request. Pay once. Own it forever. No subscription.

Bannerbear charges $49/month for this. Placid charges $19+/month. OG Image Studio is a $39 one-time purchase (or free — it's MIT, build it yourself below) that runs on your laptop or a $5 VPS.

Screenshot

☕ Skip the setup — get the 1-click installer

Don't want to clone, build, and configure? Grab the packaged installer with everything pre-wired:

https://whop.com/onetime-suite

Features

  • Visual template editor — canvas with drag positioning + snap guides, layers panel, live preview that matches server output pixel-for-pixel (same HTML renderer on both sides)
  • Layer types — text (bundled fonts, weight, color, align, max-width wrap, auto-shrink to fit), images (upload or URL, cover/contain/fill, border-radius, opacity), shapes (rect/pill with opacity), backgrounds (solid, gradient, image)
  • Sizes for every network — OG/blog 1200×630, X large card 1600×900, Instagram square 1080×1080, Instagram story 1080×1920, LinkedIn 1200×627 (plus fully custom dimensions)
  • {{variables}} — type {{title}} in any text layer (or image URL) and the template instantly becomes an API endpoint with that parameter
  • Render APIGET /api/render/:templateId?title=...&key=... returns a PNG. Deterministic, server-side, rendered with bundled Chromium (Puppeteer). Drop the URL straight into your og:image meta tag.
  • Bulk CSV → zip — upload a CSV, get one PNG per row. Batch 500 episode cards for your podcast back-catalog in one request.
  • Gallery — every API render is logged and browsable, with the exact params used
  • 5 polished starter templates — Blog Post, Podcast Episode, Product Launch, Quote Card, Event
  • 100% local — your data never leaves your machine. SQLite + filesystem. No telemetry.

Quick start

git clone https://github.com/bensblueprints/og-image-studio
cd og-image-studio
npm i          # installs deps incl. bundled Chromium (~150 MB, one time)
npm run build  # build the frontend
npm start      # → http://localhost:5309  (password: admin)

Copy .env.example to .env to set PORT, ADMIN_PASSWORD, and API_KEY. If you don't set an API key, one is generated on first run — it's shown on the API page and in the server logs.

🖥️ Desktop mode

Run it as a desktop app, or deploy to a $5 VPS when you need it public:

npm run desktop

A native window opens, auto-logged-in as admin, with data stored in your OS profile. Same code, same features — the Electron wrapper just boots the local server for you. (Desktop mode uses your installed Node.js to run the server process.) npm run dist builds a Windows NSIS installer via electron-builder.

🐳 Docker (VPS deployment)

docker compose up -d

Ships with Chromium and all render dependencies baked in. Generated images and the SQLite database live in the og_data volume.

The API

This is the headline feature: every template you design is instantly a REST endpoint.

Render an image

GET /api/render/:templateId?title=...&author=...&key=YOUR_API_KEY

Any {{variable}} used in the template becomes a query parameter. Auth via ?key= or the X-Api-Key header. Returns image/png.

curl -o card.png "http://localhost:5309/api/render/JA4fNNDHkaUn?title=My%20Post&author=Ben&key=ogs_..."
// Node / serverless — generate an OG image for every blog post
const params = new URLSearchParams({ title: post.title, author: post.author });
const res = await fetch(`https://og.yourdomain.com/api/render/${TEMPLATE_ID}?${params}`, {
  headers: { 'X-Api-Key': process.env.OG_API_KEY },
});
const png = Buffer.from(await res.arrayBuffer());
<!-- Or point your meta tags straight at it — images render on demand -->
<meta property="og:image"
      content="https://og.yourdomain.com/api/render/TEMPLATE_ID?title=Dynamic%20Title&key=KEY" />
<meta name="twitter:card" content="summary_large_image" />

Extras: &download=1 forces a download disposition, &nosave=1 skips the gallery log.

Bulk render (CSV → zip)

POST /api/render/:templateId/bulk?key=YOUR_API_KEY

Send CSV as the raw body (Content-Type: text/csv) or as a multipart file field named csv. Column headers map to template variables; an optional _filename column names each file. Returns a zip of PNGs (max 500 rows).

curl -X POST "http://localhost:5309/api/render/TEMPLATE_ID/bulk?key=KEY" \
  -H "Content-Type: text/csv" \
  --data-binary @episodes.csv -o cards.zip
title,author,_filename
"How We Cut Our Cloud Bill",Ben,post-001
"Shipping in Public",Sarah,post-002

Template management (admin session)

Method Path What
GET /api/templates List templates (+ detected variables)
POST /api/templates Create ({name, data})
PUT /api/templates/:id Update
POST /api/templates/:id/duplicate Duplicate
DELETE /api/templates/:id Delete
GET /api/gallery Generated image log

vs. Bannerbear

OG Image Studio Bannerbear
Price $39 once (or free, MIT) $49/month ($588/yr)
API renders Unlimited 1,000/mo on Starter
Templates Unlimited 10 on Starter
Data location Your machine / your VPS Their cloud
Rate limits None Yes
Works offline Yes No
Source code Yours, MIT Closed
Pays for itself in 24 days

Tech stack

  • Server — Node 20+, Express, better-sqlite3, Puppeteer (bundled Chromium) for deterministic HTML→PNG rendering
  • Frontend — React (Vite), Tailwind CSS, Framer Motion, Lucide, Zustand
  • Fonts — Inter, Space Grotesk, Playfair Display, JetBrains Mono bundled via Fontsource and base64-embedded at render time (fully offline, deterministic output)
  • Desktop — thin Electron wrapper around the identical Express server
  • One renderer, everywhere — the editor preview and the render engine share the same shared/renderHtml.js, so WYSIWYG actually means it

Development

npm start      # API server on :5309
npm run dev    # Vite dev server on :5310 (proxies /api to :5309)
npm test       # smoke test: boots server, renders PNGs, checks dims/hashes/auth/bulk

License

MIT © 2026 Ben (bensblueprints)

About

Self-hosted OG/social image generator — template editor with variables + render API. Bannerbear alternative: $39 once vs $49/mo. Desktop app or VPS.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages