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

metaplate

v0.8.4

Published

Typed social-image contracts for TypeScript: rendering, metadata, routes, and verification.

Readme

Metaplate

CI CodeQL npm Socket Badge License: MIT

Composable, framework-neutral Open Graph image tooling for TypeScript.

Define your social images once. Render, serve, and publish them consistently across your TypeScript app.

Metaplate turns a single branded JSX plate into the complete Open Graph image pipeline. Use the same definition to render SVG or raster images in several sizes, serve them from Node-compatible or edge routes, generate matching Open Graph and X metadata, emit the <meta> tags, manage fonts, produce predictable image URLs, and verify the files you ship, locally or at a deployed URL.

The same metadata also produces Open Graph video and audio tags, X player and app cards, Schema.org ImageObject JSON-LD, and Adaptive Cards for Teams, Slack, and Discord previews.

It works with plain Node, static build scripts, Next.js, Astro, React Router, SvelteKit, Express, Bun, and Deno, and on Deno-based edges such as Netlify Edge Functions and Deno Deploy, without tying your image design to a single framework.

Contents

Install

One command installs Metaplate's complete framework-neutral renderer stack:

npm install metaplate

Metaplate needs Node.js 20 or newer. With npm 7+ (and pnpm 8+), that also installs compatible versions of satori, @resvg/resvg-js, and react automatically, deduplicated against compatible versions already in the application. Package managers that do not install peers, such as Yarn, need them added explicitly:

yarn add metaplate satori @resvg/resvg-js react

Dependency behavior

next and @resvg/resvg-wasm are the optional peers: Next applications already own their framework version, non-Next applications should not download it, and only metaplate/edge needs the WebAssembly renderer. The renderer peers are bounded to the release-tested major/minor lines instead of silently accepting unknown breaking releases.

Dependencies load only when their entry point renders, so importing metadata helpers does not initialize Satori or Resvg's native binding. Plain { type, props } authoring also remains independent of React APIs and React types; the React runtime is included by the install so JSX works immediately.

metaplate/next no longer re-exports ImageResponse. Import it from next/og directly if a plate needs it:

import { ImageResponse } from "next/og";

Quick start

Define the design once with createNodeOg. The component is Satori-compatible JSX, not browser DOM: containers with more than one child use flex, and a root that fills the card with padding needs boxSizing: "border-box" (see plate constraints). The font comes from Fontsource, so install it too: npm install @fontsource/inter (see the fonts guide).

// src/lib/og.tsx
import { fontsourceFontLoader } from "metaplate/fonts";
import { createNodeOg } from "metaplate/node";

export const og = createNodeOg<{ title: string; alt: string }>({
  alt: (copy) => copy.alt,
  fonts: fontsourceFontLoader([{ font: "inter", weight: 700 }]),
  headers: { "Cache-Control": "public, max-age=86400" },
  component: (copy) => (
    <div
      style={{
        boxSizing: "border-box",
        width: "100%",
        height: "100%",
        display: "flex",
        alignItems: "center",
        background: "#111",
        color: "#fff",
        fontFamily: "Inter",
        fontSize: 72,
        padding: 72,
      }}
    >
      {copy.title}
    </div>
  ),
});

The same plate renders bytes, a complete artifact with its metadata, and Fetch API responses for any framework route:

const png: Uint8Array = await og.render(copy);
const svg: string = await og.renderSvg(copy);
const artifact = await og.artifact("/posts/hello", copy);
const response: Response = await og.response(copy);
const fetchable = og.fetchableFrom((request: Request) => ({
  title: new URL(request.url).pathname,
  alt: "Social card",
}));

Where to go next

  • A static Next.js site? Static Next.js sites takes you from the first file to the post-deploy check, with a complete, type-checked example.
  • A particular design? Card recipes covers text beside a photograph, long titles, several fonts, one card per record, and more.
  • Making sure a card never ships broken? Testing your cards shows which check catches what, including an offline audit of a whole export.
  • On an older version? Upgrading lists each breaking change and how to compare your cards before and after.
  • Looking up an option or method? The plate reference lists them all, and the API reference lists every export.

Guides

Each guide below is a summary; the linked page has the full reference.

Rendering and routes

render returns PNG by default, and an output encoder produces JPEG, WebP, or anything else from the same raw pixels. handler and handlerFrom plug into Fetch-based routes in Next.js, Astro, React Router, and SvelteKit, and render feeds Express or a build script. plate.cached() renders each distinct copy once, keyed by the plate's design and the copy, answers If-None-Match with 304 Not Modified, and keeps a signed route signed. Plates are Satori layouts, not DOM, so read the plate constraints before designing one. Opt-in render guards fail or report a card with text no font covers, text laid out off the canvas, or (Node and edge) a single-color image, instead of shipping it; they are off by default and unavailable through metaplate/next. Rendering guide

Static files with metaplate render

metaplate render renders a whole site's cards for static hosting. It loads a module whose default export is { plate, pages: [{ route, copy }] }, writes every page at every size to the path its metadata URL names, verifies each file, and records them in a checksummed manifest. --target also fails a card that breaks a platform's rules, such as WhatsApp's 600 KB limit. --incremental re-renders only the pages whose copy, plate, or installed renderer changed.

npx metaplate render og.render.mjs --out public

Render CLI guide

Live preview with metaplate preview

metaplate preview serves a local gallery of the same render module: every page at every size with its metadata and --target checks, a switch for Satori's layout debug boxes, and 1.91:1, 2:1, and 1:1 crop overlays. Saving the module or a local file it imports reloads every open gallery.

npx metaplate preview og.render.mjs

Preview guide

Signed image routes

A dynamic image route can refuse every URL your pages did not emit. plate.signedMetadata(route, copy, { secret }) signs each image URL with HMAC-SHA-256 as an extra path segment, and plate.handlerFrom(resolve, { signed: { secret } }) answers an unsigned or tampered path with 403 before resolving copy or rendering. It runs on Web Crypto in Node and on the edge, supports secret rotation, and is opt-in; static files need none of it. Signed routes guide

Framework and runtime support

Every supported framework and runtime is listed with the official reference it follows and the release evidence behind it, from packed-tarball fixtures to dated hosted deployments. Support matrix

Edge runtimes

metaplate/edge renders the same plates through @resvg/resvg-wasm with no Node built-ins. It runs on Deno-based edges such as Netlify Edge Functions and Deno Deploy, and not on Cloudflare Workers or Vercel Edge, which forbid the run-time WebAssembly compilation Satori needs. Edge guide

Next.js

metaplate/next renders through Next's own next/og pipeline and keeps the same route and metadata pattern. The guide also covers static export with basePath and JPEG or WebP cards through the Node renderer. Next.js guide

Square and landscape variants

One plate can declare variants such as a 1080x1080 square beside the 1200x630 card. The component receives { variant, size } and lays out each size itself, and plate.variant(name) gives the full plate API for one size. Variants guide

Metadata and meta tags

The root metaplate entry builds Open Graph and X metadata with no renderer or framework, including per-channel images and Open Graph video and audio. socialMetaTags and socialMetaHtml emit the <meta> tags for pages that write their own <head>, including validated og:locale, article:, and Discord accent-color and timestamp tags. An opt-in version, or a plate's version: "copy", adds a ?v= token to published image URLs so crawlers that cache images by URL fetch a changed card, while file paths stay unchanged. Metadata guide

X player and app cards

twitter.card can be "player" or "app", with the payload each one requires checked against X's published rules. nextTwitterMetadata maps them to Next.js metadata. X cards guide

Social compatibility profiles

socialImageCompatibility checks an image descriptor against each platform's published preview rules, such as LinkedIn's minimum size, Discord's accepted formats, or WhatsApp's 600 KB limit, without network requests. Platforms that publish no rules, such as Instagram and Telegram, are reported as unknown. Profiles guide

Teams, Slack, and Discord previews

Chat clients build link previews from the same meta tags, so no app is needed. For bots and webhooks, socialImageAdaptiveCard builds an Adaptive Card from the same metadata. Chat previews guide

Schema.org image metadata

socialImageJsonLd describes the same images as a schema.org ImageObject in JSON-LD, and socialImageJsonLdScript serializes it safely for a <script> tag. JSON-LD guide

Fonts

Satori needs the bytes of every face it renders. Loaders read them from project files, Fontsource, other npm packages, or bytes you supply, and memoize one copy for every render. The languageFonts plate option draws Japanese, Arabic, Hebrew, and other scripts the plate's fonts lack, offline: fontsourceLanguageFontLoader reads only the Noto subset files the copy needs from installed Fontsource packages. Fonts guide

Emoji

The emoji plate option draws emoji as images instead of missing-glyph boxes. packageEmojiLoader from metaplate/fonts reads them offline from a set the application installs, such as @twemoji/svg, and emojiLoader from metaplate/emoji takes any source, including your own origin on an edge runtime. Metaplate bundles no artwork; the guide covers each set's license. Emoji guide

Verifying images

metaplate verify checks generated files for dimensions, format, structure, and platform rules, and metaplate verify-url runs the same checks on a deployed URL under a hardened fetch policy. metaplate verify-page audits a whole page: it reads the page's og:image, twitter:card, twitter:image, and JSON-LD images and verifies every image they name. verify takes files, directories, and globs, and --require-content decodes PNG and JPEG and fails an image whose every pixel is the same color. --baseline DIR compares each card with a saved copy and fails one that changed, with a side-by-side diff image, so a Satori or font upgrade cannot change cards unnoticed. runCli from metaplate/cli runs any command from a script without a shell. In code, verifySocialImage checks bytes against their published descriptor, and its checkUrl: false skips the HTTPS rule for a local or CI build that is never crawled. Verification guide and page audit guide

Deployment routes

Use a real .png or .jpg file on static hosts, the provider's Node runtime for metaplate/node, and metaplate/edge on Deno-based edges. Hosted certifications cover Vercel Functions, Next.js on Vercel, Netlify Functions, Netlify Edge Functions, and Deno Deploy, each from a dated deployment whose sources are in examples/hosted. The current status of every route is in deployment-evidence.json. Deployment guide

Entry points

  • metaplate — framework-free paths, dimensions, Open Graph and X metadata (including video and audio, and X player and app cards), cache-busting image URL versions (socialImageVersion), <meta> tag serialization, Schema.org JSON-LD, Adaptive Cards, social compatibility profiles, and byte-level social image verification.
  • metaplate/render — Satori-based SVG generation, with the missingGlyphs and overflow render guards (RenderGuardError). Satori is installed automatically.
  • metaplate/node — SVG, PNG, raw pixels, and any format a supplied encoder produces, plus Fetch API responses, with every render guard including blank. Satori and Resvg are installed automatically. Also the hardened remote fetcher behind verify-url and verify-page (fetchRemoteImage, verifyRemoteImage, verifyRemotePage, extractPageSocialMetadata).
  • metaplate/edge — PNG, raw pixels, and Fetch API responses (with every render guard) through @resvg/resvg-wasm for Deno-based edges such as Netlify Edge Functions, and other runtimes that allow run-time Wasm compilation; not Cloudflare Workers. No Node built-ins. Needs @resvg/resvg-wasm and the caller-supplied @resvg/resvg-wasm/index_bg.wasm and satori/layout.wasm modules.
  • metaplate/next — native Next.js ImageResponse adapter, nextTwitterMetadata for X player and app cards in Next metadata, and nextPageMetadata/nextPageViewport for page-level tags. Needs next.
  • metaplate/font-data — runtime-neutral normalization and memoization for application/framework-provided bytes, and languageFontLoader for per-language fallback fonts from any byte source. No peers or Node built-ins.
  • metaplate/fonts — project-file, Fontsource, generic npm-package, and application-byte font loading, per-language fallback fonts from installed Fontsource packages (fontsourceLanguageFontLoader), plus installed emoji packages (packageEmojiLoader), for Node-compatible runtimes. No peers.
  • metaplate/emoji — runtime-neutral emoji images for the emoji plate option (emojiLoader, twemojiName). No peers or Node built-ins; the installed-package reader, packageEmojiLoader, is in metaplate/fonts.
  • metaplate/png — PNG header inspection and dimension verification. No peers.
  • metaplate/image — dimension and structural verification for SVG, PNG, JPEG, WebP, and GIF, and imageAsset/imageAssetLoader for embedding checked image bytes in a plate. No peers or Node built-ins.
  • metaplate/assets — Node readers for plate images: project files (readImageAsset, fileImageLoader) and remote images fetched only from allowlisted origins (remoteImageLoader). No renderer peers.
  • metaplate/cli — runCli(args) runs any metaplate command in-process and resolves to its exit code, for build scripts that would otherwise spawn the binary through a shell.

API reference lists every export by entry point, with the guide for each and the constants no guide covers.

License

MIT