npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

og-card-generator

v1.0.0

Published

Generate branded Open Graph / social share images (1200x630) that render correctly on serverless headless Chromium, by embedding the font as base64. No system-font tofu.

Readme

og-card-generator

Generate branded Open Graph / social share images (1200x630) for every page, that actually render on serverless.

When you generate OG images at build time or on the edge with headless Chromium (Vercel, AWS Lambda, Cloudflare), the runtime ships no system fonts — so your text renders as empty boxes (tofu) even though it looked perfect locally. That single gotcha breaks most home-grown OG-image setups.

og-card-generator side-steps it by embedding the font as base64 directly in the card, so it renders identically everywhere, with no network fetch and no reliance on system fonts.

Example card generated by og-card-generator

  • Zero-dependency core (cardHtml returns an HTML string you can render however you like)
  • Optional one-call PNG via puppeteer (renderToPng)
  • Auto-sizes the headline, fully themeable (colors, accent, fonts)
  • Works at build time (prerender), on the edge, or in a serverless function

Install

npm install og-card-generator

Quick start

import { cardHtml, renderToPng, loadFontBase64 } from 'og-card-generator';

const fontBase64 = loadFontBase64('./fonts/inter-600.woff2');

// 1) Just the HTML (zero deps) — screenshot it with whatever you already use.
const html = cardHtml({
  title: 'How much does a website cost?',
  eyebrow: 'Acme Studio',
  footer: 'acme.com/pricing',
  fontBase64,
});

// 2) Or render straight to a PNG buffer (needs: npm i puppeteer)
const png = await renderToPng({
  title: 'How much does a website cost?',
  eyebrow: 'Acme Studio',
  footer: 'acme.com/pricing',
  fontBase64,
  accent: '#7c5cff',
});
import { writeFileSync } from 'node:fs';
writeFileSync('og.png', png);

Then point each page's meta at the image:

<meta property="og:image" content="https://acme.com/og/pricing.png" />
<meta name="twitter:image" content="https://acme.com/og/pricing.png" />

Serverless rendering (Vercel / Lambda)

Pass your own launcher so you can use puppeteer-core + @sparticuz/chromium:

import chromium from '@sparticuz/chromium';
import puppeteer from 'puppeteer-core';

const png = await renderToPng({
  title: 'Built for your market',
  fontBase64,
  launch: () => puppeteer.launch({
    args: chromium.args,
    executablePath: chromium.executablePath(),
    headless: chromium.headless,
  }),
});

Because the font is embedded, the font-less serverless Chromium still renders the text correctly.

Options

| Option | Default | Notes | |--------------|-----------------------|----------------------------------------------------| | title | placeholder | Headline. Auto-sizes by length. | | eyebrow | YOUR BRAND | Small label above the title. | | footer | yourdomain.com | Bottom-left line (e.g. the page URL). | | fontBase64 | '' | base64 of a woff2/ttf. Use loadFontBase64(path). | | fontFamily | CardFont | CSS family name for the embedded font. | | width | 1200 | Card width. | | height | 630 | Card height. | | background | #0d1f22 | Card background. | | accent | #93B7BE | Bar, eyebrow, footer color. | | text | #F1FFFA | Title color. | | titleSize | auto | Override the auto title size (px). | | scale | 1 | renderToPng deviceScaleFactor (2 = retina). | | launch | puppeteer default | renderToPng custom browser launcher. |

Run the example:

npm i puppeteer
node example/generate.mjs   # writes example/out.png

Fonts

The example/ folder includes Inter (SIL Open Font License 1.1) for a runnable demo. Bring any woff2/ttf you like for your own brand; only you decide what font ships.

License

MIT for the code. See LICENSE. The bundled Inter font is under the SIL OFL 1.1.


Built and maintained by Clap Digital, a full-stack web and AI agency. We use this to give every page on our site its own branded share card. If it saves you time, a star is appreciated.