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

stippler

v0.1.0

Published

WSJ-hedcut-style stipple portraits from photos: U2Net cutout + weighted Voronoi stippling, output as compact SVG

Readme

stippler

WSJ-hedcut-style stipple portraits from photos, as compact SVGs.

Weighted Voronoi stippling (Secord 2002): dots are seeded by darkness, then relaxed with Lloyd iterations so spacing stays even while density follows tone. U2Net background removal and head-normalised framing give every portrait the same bust-crop silhouette, and an oval vignette fades it out toward the edges.

Originally a Python pipeline built for the Bald Man Scale post — the 24 SVGs it published live in svg/, with per-subject attribution in credits.json.

Install

npm install -g stippler   # or: npx stippler photo.jpg

Requires Node 20+. sharp and onnxruntime-node ship native binaries for macOS (arm64/x64), Linux (x64/arm64 glibc), and Windows x64; Alpine/musl is unsupported. On first run with background removal, the u2net model (~176 MB) downloads once to ~/.cache/stippler/u2net.onnx.

Usage

stippler photo.jpg                         # -> photo.svg
stippler https://example.com/face.jpg      # URLs work too
stippler photo.jpg -o out.png --scale 3    # extension picks the format
stippler photo.jpg --crop 0.2,0,0.8,0.9    # fractional pre-crop for awkward framing
stippler photo.jpg --no-cutout             # skip U2Net; plain top-centre crop

| Flag | Default | Meaning | | --- | --- | --- | | -o, --out | <input>.svg | Output path; .svg or .png decides the format | | --dots | 2200 | Number of stipple dots | | --iters | 45 | Lloyd relaxation iterations | | --gamma | 1.45 | Darkness exponent; higher concentrates dots in shadows | | --edge-boost | 0.4 | Edge-detection contribution to dot density | | --seed | 7 | PRNG seed; same seed, same output | | --ink | #1a1a1a | Dot colour (hex) | | --scale | 2 | PNG scale factor over the 360x432 canvas | | --crop | — | Fractional pre-crop x0,y0,x1,y1 in [0, 1] | | --no-cutout | — | Skip background removal and head framing | | --model-path | auto | Explicit u2net.onnx path (never downloads) |

EXIF orientation is applied automatically, so phone photos come out upright. Output SVGs encode dots as six round-cap stroke paths bucketed by radius (~35 KB raw, ~11 KB gzipped per head).

Library

import { readFile, writeFile } from "node:fs/promises";
import { generateHedcut } from "stippler";

const result = await generateHedcut(await readFile("photo.jpg"), {
  dots: 2400,
  modelPath: "/path/to/u2net.onnx", // omit with cutout: false
});
if (result.success) {
  await writeFile("out.svg", result.data.svg);
}

generateHedcut performs no filesystem or network access beyond reading the model file — input acquisition, model download, and output writing stay with the caller (the CLI handles all three).

Development

bun install
bun run test        # vitest
bun run check       # biome lint + format
bun run typecheck   # tsc --noEmit
bun run build       # bunup (types) + esbuild (dist/)

The cutout end-to-end test is gated: set STIPPLER_MODEL_PATH to a local u2net.onnx to include it. Releases are tag-driven (v*) and publish to npm via OIDC trusted publishing — see .github/workflows/release.yml.