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

@argos-ci/mask-fingerprint

v0.1.3

Published

Fast, deterministic visual diff fingerprinting for PNG images, exposed as a Node.js native module via N-API.

Downloads

798

Readme

mask-fingerprint

Fast, deterministic visual diff fingerprinting for PNG images, exposed as a Node.js native module via N-API.

This library takes a PNG diff image (for example red-pixel visual diffs) and produces a stable equality fingerprint.
Two diffs that are visually very close will produce the same fingerprint, enabling:

  • fingerprintA === fingerprintB
  • database indexing
  • grouping and deduplication
  • joins without custom comparison logic

The core algorithm is written in Rust for performance and exposed to Node.js.

What problem this solves

Classic perceptual hashes require distance comparisons, which do not work well with SQL indexes or strict equality.

This project instead:

  • normalizes the diff mask
  • quantizes spatial density
  • hashes a coarse representation

The result is tolerant equality, not approximate similarity.

How it works

  1. Decode PNG into RGBA
  2. Extract a binary mask of red pixels
  3. Optional dilation to absorb small pixel noise
  4. Crop to the bounding box
  5. Optional square padding
  6. Split into a small grid (8×8, 16×16, or 32×32)
  7. Compute per-cell red density
  8. Quantize densities into bins
  9. Pack bits and hash with FNV-1a 64-bit
  10. Return a deterministic string key

Small local differences usually do not change the final fingerprint.

Installation

Requirements

  • Node.js 24 or newer
  • Rust stable
  • Cargo

Install dependencies

pnpm install

or

npm install

This builds the native module.

Usage

import fs from 'node:fs'
import { fingerprintDiff } from 'mask-fingerprint'

const png = fs.readFileSync('diff.png')

const fingerprint = await fingerprintDiff(png, {
  gridSize: 16,
  dilateRadius: 1,
  padToSquare: true,
  densityThresholds: [0.002, 0.02, 0.08],
  redThreshold: {
    rMin: 200,
    gMax: 90,
    bMax: 90,
    aMin: 16,
  },
})

console.log(fingerprint)
// v1:g16:d1:t0.002,0.02,0.08:3fa1c2e9a4b8d210

The returned value is designed to be stored in a database, indexed, and compared using strict equality.

API

fingerprintDiff(buffer, options?)

Returns a Promise<string>.

Parameters

buffer

  • Node.js Buffer
  • Raw PNG file contents

options (optional)

{
  gridSize?: 8 | 16 | 32        // default: 16
  dilateRadius?: 0 | 1          // default: 1
  padToSquare?: boolean         // default: true

  densityThresholds?: number[]  // default: [0.002, 0.02, 0.08]
                                // sorted, values between 0 and 1

  redThreshold?: {
    rMin?: number               // default: 200
    gMax?: number               // default: 90
    bMax?: number               // default: 90
    aMin?: number               // default: 16
  }
}

Returns

string

A deterministic fingerprint string suitable for equality comparison and indexing.

Supported PNG formats

  • RGBA
  • RGB
  • Grayscale
  • Grayscale with alpha
  • Indexed or palette PNGs

Palette and low bit-depth images are automatically expanded.

Performance characteristics

  • Linear time in number of pixels
  • No heavy floating-point operations
  • Minimal allocations in hot paths
  • Suitable for batch processing

Typical workloads handle thousands of diffs per second.

When to use this

Good fit:

  • Visual regression testing
  • Screenshot diff deduplication
  • CI artifact clustering
  • Database-backed visual change tracking

Not a good fit:

  • General image similarity search
  • Large geometric transformations
  • Rotation or strong scale invariance

This library is intentionally optimized for diff masks, not arbitrary images.

Development

cargo check
cargo test

Rebuild the native module:

pnpm build

License

MIT