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

kisscut

v0.1.0

Published

Sticker outlines (Cloudinary outline:fill equivalent), fit/fill resize, and rotation for raster images. Pure TypeScript, zero dependencies, browser + Node.

Downloads

152

Readme

kisscut

Sticker outlines for raster images, an open-source equivalent of Cloudinary's e_outline:fill. Also does fit/fill resize and rotation. Pure TypeScript, zero runtime dependencies, ~5 KB minified, runs in browsers (ImageData) and Node (skia-canvas or raw RGBA buffers).

A kiss cut is the sticker cut that traces just outside your artwork. Give this library a transparent PNG and it returns the artwork wrapped in a constant-width, anti-aliased outline, with enclosed holes filled so the result prints as one sticker.

One of these was made by Cloudinary, the other by kisscut, locally (kisscut is on the left):

kisscut vs Cloudinary

The raw per-pixel difference, unamplified. Black means identical; the faint red hairlines along the edges are the entire difference:

difference heatmap

Install

npm install kisscut

Usage

import { outline, transform } from 'kisscut'

// Anything shaped like { data: Uint8ClampedArray, width, height } works.
// Browser ImageData is structurally compatible.
const imageData = context.getImageData(0, 0, canvas.width, canvas.height)

const { image, pad } = outline(imageData, {
  width: 18,            // outline radius in px
  color: '#ffffff80',   // '#rrggbbaa' and 'rgb:rrggbbaa' accepted, alpha works natively
  fillHoles: true       // fill enclosed transparent regions (default)
})

// The canvas grows by `pad` on every side so the outline is never clipped
context.putImageData(new ImageData(image.data, image.width, image.height), x - pad, y - pad)

transform() chains Cloudinary-style operations (resize, then rotate, then outline):

const { image, pad } = transform(imageData, {
  width: 563, height: 563, crop: 'fit',   // c_fit / c_fill parity
  angle: -90,                              // multiples of 90, or 'auto_left'
  outline: { width: 17.6, color: 'white' }
})

The building blocks are exported too: distanceTransform, dilateCoverage, fillHoles, resize, rotate, parseColor, and similarity (overlap-score two images and get a difference heatmap).

How it works

  1. Read alpha coverage onto a padded grid
  2. Exact Euclidean distance transform (Felzenszwalb-Huttenlocher, O(n)), seeded sub-pixel from alpha coverage so the outline follows the true edge, not pixel centers
  3. Smoothstep over the distance field: constant-width outline, round joins, anti-aliased edges
  4. Holes filled after dilation, matching Cloudinary. Gaps narrower than 2x the width close, and the newly enclosed interior fills
  5. The colored outline layer is composited under the artwork. Semi-transparent colors just work, no need for Cloudinary's o_/l_fetch/fl_layer_apply double-render workaround
  6. Resize is separable Catmull-Rom in premultiplied-alpha space

Fidelity

The test suite compares output against real Cloudinary renders committed as fixtures. Images are overlapped and scored on per-pixel agreement, where 1.0 is pixel-identical. Measured scores are 0.990 to 0.998; every case must pass 0.988. What remains is single-pixel edge anti-aliasing against a proprietary renderer. Run yarn compare <dir> to reproduce the scores and heatmaps.

kisscut vs Cloudinary, line art

difference heatmap, line art

Performance

Single-threaded, Node 24, desktop:

| Image | Outline width | Time | | --- | --- | --- | | 800×800 | 25 px | ~60 ms | | 1600×1600 | 50 px | ~230 ms | | 3200×3200 | 100 px | ~940 ms |

vs. a Cloudinary request

Same transform, measured against the public demo cloud:

| Path | Time | | --- | --- | | Cloudinary, fresh transform (any new artwork) | ~1,000 ms | | Cloudinary, CDN-cached repeat of the same URL | ~36 ms | | kisscut, locally, 1126×1126 (2x retina of a 563 px preview) | ~134 ms |

For previews of user-uploaded artwork every image is new, so Cloudinary always pays the fresh-transform price. Running locally is roughly 7x faster there, works offline, and a local result can be cached for repeat renders just like a CDN would.

Development

yarn                # install
yarn test           # unit + property + Cloudinary-parity tests
yarn demo           # interactive demo: drag in a PNG, tweak width/color/opacity
yarn bench          # benchmarks at 800/1600/3200 px
yarn compare out/   # overlap scores + difference heatmaps vs Cloudinary fixtures
yarn build          # dist/ (ESM + CJS + d.ts)

Roadmap

  • Unifying outline for multi-part artwork: MST capsule bridges so disconnected pieces become one printable sticker (beyond what Cloudinary offers)
  • Vector cutline: marching squares + simplification + smoothing to an SVG path, for actual die lines

License

MIT