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

@oh-just-another/exporter

v0.57.3

Published

Hi-res image and PDF export for @oh-just-another/scene documents.

Readme

@oh-just-another/exporter

npm version

Document-grade export of @oh-just-another/scene documents — high-resolution PNG with DPI metadata, vector PDF, world-coordinate cropping. Builds on top of @headless (which itself uses @renderer-svg).

Install

pnpm add @oh-just-another/exporter
# Peer deps — install only the ones you need:
pnpm add @resvg/resvg-js   # PNG  (~3 MB wasm)
pnpm add pdfkit svg-to-pdfkit   # PDF

All three peers are optional — the package only requires the ones for the formats you call into.

Usage

import { writeFile, readFile } from "node:fs/promises";
import { exportPng, exportPdf } from "@oh-just-another/exporter";

const scene = await readFile("scene.json", "utf8");

// High-resolution PNG with print DPI metadata.
await writeFile(
  "[email protected]",
  await exportPng(scene, { scale: 2, dpi: 300, background: "#ffffff" }),
);

// Crop a region of the scene.
await writeFile(
  "thumb.png",
  await exportPng(scene, { region: { x: 0, y: 0, width: 400, height: 300 } }),
);

// PDF for printing — A4 portrait by default.
await writeFile(
  "scene.pdf",
  await exportPdf(scene, { pageSize: "Letter", orientation: "landscape", title: "Diagram" }),
);

API

| Name | Purpose | | ------------------------------- | ----------------------------------------------------------------------------------------------- | | exportPng(scene, options?) | Scene → PNG Uint8Array. Optional region, scale, background, dpi. | | exportPdf(scene, options?) | Scene → PDF Uint8Array. Optional region, pageSize, orientation, margin, doc metadata. | | setPngDpi(png, dpi) | Standalone helper to embed a pHYs chunk into any PNG. | | sceneForFrame(scene, id) | Sub-scene scoped to a frame element's bounds. | | sceneForRegion(scene, region) | Sub-scene scoped to a world-coordinate region. | | BaseExportOptions | Shared: region, width, height, background. | | ExportPngOptions | Adds scale, dpi. | | ExportPdfOptions | Adds pageSize, orientation, margin, title, author, subject. | | ExportRegion, PdfPageSize | Type aliases re-exported for convenience. |

Design notes

  • Crop = synthetic viewport. A region is implemented by handing the renderer a viewport with pan = -region and size = region.{w,h}. No extra clip-rect logic in the SVG/PDF pipeline — the renderer naturally produces an image of the right size.
  • DPI metadata via direct PNG chunk insertion. resvg-js doesn't expose output pHYs, so setPngDpi walks the PNG byte stream, drops any existing pHYs, and writes a fresh one (with a hand-rolled CRC32) right before the first IDAT. Zero deps, ~100 lines.
  • PDF via pdfkit + svg-to-pdfkit, not via PNG-embed. Embedding a raster PNG into a PDF would lose vector quality and inflate file size. Going through SVG keeps fonts and shapes crisp at any zoom.
  • Optional peer deps over direct deps. Consumers pulling only exportPng don't get pdfkit's footprint; PDF-only callers don't drag in resvg. Each entry point loads its peers dynamically via import(/* @vite-ignore */ specifier) so bundlers don't bake them in.
  • A4 / Letter etc. as string constants. Custom sizes via { width, height } in PDF points (1pt = 1/72in). The CLI accepts the same plus a WxH shorthand.