Forge Open Graph / social-share images in your CI pipeline — a free GitHub Action.
og-forge renders crisp 1200×630 OG images for any repo or site straight from a workflow step. Satori draws the card as an SVG, resvg bakes it to a PNG, and the fonts ship vendored in the repo — so a render is byte-for-byte reproducible on any runner with no headless browser, no Chrome, and no external service.
- 🎨 3 templates —
default,blog,article— each indarkandlight - ⚡ ~40 ms per render, no browser spawned
- 📦 Fonts vendored (Noto Serif · Noto Sans · JetBrains Mono, all SIL OFL) — zero network at runtime
- 🆓 MIT-licensed, free forever
Add this to .github/workflows/og.yml:
name: forge-og
on: [push]
jobs:
og:
runs-on: ubuntu-latest
steps:
- uses: percymcn/og-forge@v0.1
with:
title: "Why we killed the headless browser"
description: "Satori + resvg, 40ms a card."
template: blog # default | blog | article
theme: dark # dark | light
domain: blog.example.dev
tag: ENGINEERING
author: Dana Okafor
output: public/og.png
# then: commit public/og.png, or actions/upload-artifact, etc.The step writes the PNG to output inside ${{ github.workspace }}. Commit it (or upload it as
an artifact / attach it to a release) and point your page at it:
<meta property="og:image" content="https://example.dev/og.png" />
<meta name="twitter:card" content="summary_large_image" />| Input | Required | Default | Description |
|---|---|---|---|
title |
✅ | — | Headline text. |
description |
'' |
Sub-headline / summary. | |
template |
default |
default · blog · article. |
|
theme |
dark |
dark · light. |
|
domain |
'' |
Small mono label, top-left (e.g. your host). | |
tag |
'' |
Category pill, top-right (e.g. GUIDE). |
|
author |
'' |
Byline in the footer. | |
watermark |
'' |
Footer credit, bottom-right (empty = none). | |
output |
og.png |
Output PNG path, relative to the workspace. |
| Output | Description |
|---|---|
image-path |
Path of the generated PNG. |
bytes |
Byte size of the generated PNG. |
| Template | Feel | Type |
|---|---|---|
default |
General purpose, product/launch cards | Noto Sans, accent bar |
blog |
Editorial, italic serif subhead | Noto Serif |
article |
Minimal magazine, high contrast, rules | Noto Sans, 800-weight title |
See all six variants in samples/ or open demo/index.html.
npm install
node render.mjs --title "Hello world" --template article --theme light --out og.png
npm run smoke # renders all 3 templates × 2 themes and validates 1200×630 output
npm run samples # regenerate the sample gallery in samples/params ──▶ templates.mjs (VNode) ──▶ satori (SVG) ──▶ resvg (PNG) ──▶ og.png
src/templates.mjs is pure data — plain style objects, no I/O — so the visual design is easy to
read and fork. render.mjs is the portable entrypoint the Action calls; it loads the vendored
.woff fonts from assets/fonts/ and never touches the network or a browser.
MIT — see LICENSE. Bundled fonts are SIL Open Font License 1.1
(see assets/fonts/*-LICENSE.txt).
Compositing engine reused from the SnapOG / ShipShots satori pipeline. Built by the Auto Company autonomous loop.
