| name | social-preview |
| description | Generate Open Graph social preview images (1280x640) for GitHub repositories. Creates branded OG images that display when repos are shared on Twitter, LinkedIn, and Slack. Supports custom templates, dark/light themes, and automated generation. |
| license | MIT |
| origin | custom |
| author | Rebecca Rae Barton |
| author_url | https://github.com/thatrebeccarae |
| metadata | {"version":"1.0.0","category":"devops","domain":"github","updated":"2026-03-19T00:00:00.000Z","tested":"2026-03-19T00:00:00.000Z","tested_with":"Claude Code v2.1"} |
Social Preview
Generate Open Graph social preview images (1280x640px) for GitHub repositories. The social preview is the single highest-leverage visual asset when repos are shared on Twitter, LinkedIn, Slack, and Discord.
Install
claude skill install social-preview
When to Use
- New public repo needs a social preview before sharing
- Rebranding a project (new colors, name change, logo update)
- Major release or launch -- refresh the preview to reflect the milestone
- Before marketing pushes (LinkedIn posts, Twitter threads, blog features)
- Audit existing repos to catch missing or outdated social previews
Usage
/social-preview generate [repo-path] # Create OG image from repo context
/social-preview audit [repo-path] # Check if social preview is set, dimensions correct
Default repo-path is the current working directory if omitted.
Procedure: Generate
Execute each step in order. Do not skip steps.
Step 0: Parse Command
Expect: /social-preview {mode} [repo-path]
Extract mode (generate or audit). If missing or invalid:
Error: Invalid or missing mode.
Usage:
/social-preview generate [repo-path]
/social-preview audit [repo-path]
STOP.
Validate repo-path is a directory containing .git. Default to cwd if omitted.
Step 1: Scan Repo for Context
Gather:
- Project name -- from
package.json name, Cargo.toml [package] name, pyproject.toml name, or directory name
- Description/tagline -- from package.json description, repo description, or ask user
- Primary language -- from file extensions, package manager files, or
gh repo view --json primaryLanguage
- Logo/icon -- check for
logo.png, logo.svg, icon.png, icon.svg, .github/logo.png, assets/logo.*, branding/logo.*
- Git remote --
git remote get-url origin to extract owner/repo
- Existing social preview --
gh api repos/{owner}/{repo} to check current state
Step 2: Select Template
Present template options to the user:
- Dark (recommended) -- Dark background (#0d1117 or #141414), light text. Highest contrast, best performance on most feeds.
- Light -- Light background (#fafbfc), dark text. Matches certain brand aesthetics.
- Minimal -- Just project name + tagline, no decoration. Clean and typographic.
Ask: "Which template? [dark/light/minimal] (default: dark)"
If the repo has established brand colors (detected from CSS variables, tailwind config, or user-specified), offer to use those as accent colors.
Step 3: Generate HTML Template
Create a standalone HTML file (1280x640px viewport) containing:
- Project name -- large, prominent, max 40 characters displayed. Use system-safe fonts only (no external font dependencies).
- One-line description/tagline -- below the name, lighter weight, max 80 characters.
- Primary language/tech icon (optional) -- simple text-based indicator or Unicode symbol. No external image dependencies.
- Author/org attribution (optional) -- small, bottom corner. GitHub username or org name.
- Background -- solid color, CSS gradient, or subtle CSS pattern (dots, grid). No external images.
Write the HTML file to {repo-path}/social-preview.html (or /tmp/social-preview-{repo-name}.html if user prefers).
Step 4: Render to PNG
Guide the user through one of three rendering paths:
Option A -- Browser screenshot (simplest, no deps):
- Open the HTML file in any browser
- Set viewport to exactly 1280x640
- Take a full-page screenshot
- Save as PNG
Option B -- Puppeteer/Playwright (automated, requires Node):
node -e "
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 640, deviceScaleFactor: 2 });
await page.goto('file:///PATH/TO/social-preview.html', { waitUntil: 'networkidle0' });
await page.screenshot({ path: 'social-preview.png', clip: { x: 0, y: 0, width: 1280, height: 640 } });
await browser.close();
})();
"
Option C -- Cloud renderer:
- Use
npx @vercel/og or a hosted OG image service if the user prefers URL-based generation.
Step 5: Set as Social Preview
Guide the user through one of two methods:
Method A -- GitHub UI:
- Go to
https://github.com/{owner}/{repo}/settings
- Scroll to "Social preview"
- Click "Edit" -> "Upload an image..."
- Upload the generated PNG
- Click "Save"
Method B -- GitHub API:
gh api repos/{owner}/{repo} \
--method PATCH \
--field "social_preview=$(base64 -i social-preview.png)"
Note: The GitHub REST API does not directly support uploading social preview images via base64. The UI method is the most reliable. For automation, use the repository settings page.
Step 6: Verify
Provide validation URLs:
- Twitter Card Validator:
https://cards-dev.twitter.com/validator
- Facebook Sharing Debugger:
https://developers.facebook.com/tools/debug/
- LinkedIn Post Inspector:
https://www.linkedin.com/post-inspector/inspect/
- Open Graph Debugger:
https://opengraph.dev/
Tell user to paste the repo URL and verify the preview renders correctly.
Procedure: Audit
Step 1: Check Repo
Validate repo-path is a git repo with a remote.
Step 2: Fetch Current Social Preview State
gh api repos/{owner}/{repo} --jq '.description, .homepage'
Check if a custom social preview image is set (GitHub auto-generates one if not).
Step 3: Report
=== Social Preview Audit: {repo-name} ===
Custom preview set: {YES / NO (using auto-generated)}
Description: {repo description or "MISSING -- add one"}
Homepage URL: {homepage or "not set"}
Recommendations:
- {actionable items: missing preview, missing description, etc.}
Run /social-preview generate to create one.
Design Principles
- Readable at thumbnail size. Social feeds show previews at ~400px wide. Text must be legible at that scale.
- High contrast. Dark backgrounds with light text outperform on most platforms. Minimum 4.5:1 contrast ratio.
- No small text. If it won't be readable at 400px wide, remove it. Project name should be 48-72px at 1280px canvas.
- 2:1 aspect ratio. 1280x640 is the standard. Platforms crop outside this ratio.
- No external dependencies. HTML must render with zero network requests. System fonts only. Inline all CSS.
- Keep text minimal. Project name + one-line tagline. Nothing else is guaranteed to be readable.
- Test at actual share size. Always preview at 400x200 before finalizing.
Key Principles
- Dark backgrounds perform better across Twitter, LinkedIn, and Slack feeds.
- Keep text to two lines maximum: name + tagline.
- Test at actual share size (400px wide), not at full resolution.
- PNG format, under 1MB. Avoid JPEG for text-heavy images (compression artifacts).
- Update the preview when the project description or branding changes.
- A missing social preview is worse than a simple one -- GitHub's auto-generated preview is generic and forgettable.
Files
- HTML template:
{repo-path}/social-preview.html or /tmp/social-preview-{repo-name}.html
- PNG output:
{repo-path}/social-preview.png
Anti-Patterns
- No external font CDN links -- system fonts only for guaranteed rendering
- No images or logos that require network requests -- inline SVG or omit
- No text below 24px at 1280px canvas (will be illegible at thumbnail size)
- No busy backgrounds or photographic backgrounds -- solid or gradient only
- No more than 3 colors total (background, primary text, accent)
- No rounded corners or complex shapes that get lost at small sizes
- Do not include full URLs in the image -- waste of space, unreadable at thumbnail