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

printcatcher

v0.1.0

Published

Node.js framework for fingerprint enrollment/verification/identification with a DigitalPersona U.are.U 4500 reader

Downloads

27

Readme

printcatcher

Node.js framework for fingerprint enrollment, verification, and 1:N identification with a DigitalPersona U.are.U 4500 reader.

Calls into the official DigitalPersona U.are.U SDK through a small compiled Fortran helper (printcatcher_cli.exe), spawned as a subprocess rather than called via direct FFI (ctypes/koffi-style dynamic FFI calls into the SDK's device-enumeration function were found to silently fail — see the main repo's README for how that was diagnosed). Windows-only.

Requirements

  • Windows, x64.
  • The official U.are.U SDK installed (provides dpfpdd.dll/dpfj.dll and the reader's device driver).
  • A U.are.U 4500 reader connected, on its normal Windows driver.

Install

npm install printcatcher

Usage

const { PrintCatcherClient, FINGERS } = require('printcatcher');

const client = new PrintCatcherClient({ templatesDir: './templates' });

client.on('waiting', () => console.log('place your finger on the sensor'));
client.on('sample', ({ sample, total }) => console.log(`sample ${sample}/${total}`));
client.on('captured', ({ imageDataUrl }) => {
    // imageDataUrl is a ready-to-use "data:image/png;base64,..." string --
    // drop it straight into <img src="..."> for a live capture preview.
});

await client.enroll('alice', { finger: FINGERS.RIGHT_THUMB });

const result = await client.verify('alice', { finger: FINGERS.RIGHT_THUMB });
// { userId: 'alice', finger: 'right-thumb', score: 0, isMatch: true }

const who = await client.identify();
// { match: 'alice__right-thumb.fmd', userId: 'alice', finger: 'right-thumb', score: 0, isMatch: true }

See examples/basic_usage.js for a runnable end-to-end script.

API

new PrintCatcherClient(options)

  • options.templatesDir — where enrolled templates are stored (default: ./printcatcher-templates).
  • options.matchThreshold — dissimilarity score cutoff for isMatch (default 5000; 0 = identical, larger = more different — tune this for your own false-accept/false-reject tolerance, this default is a starting point, not a certified security threshold).

client.enroll(userId, { finger, numSamples, timeoutMs })

Captures multiple samples (the SDK decides internally how many it actually needs, up to numSamples, default 4) and stores the resulting template. finger is one of the FINGERS constants (default FINGERS.UNKNOWN).

client.verify(userId, { finger, timeoutMs, matchThreshold })

Captures one sample and compares it 1:1 against userId's stored template for that finger. Throws if no such template is enrolled.

client.identify({ timeoutMs, matchThreshold })

Captures one sample and compares it 1:N against every enrolled template. Returns { match: null, ... } if nothing scores within the threshold.

client.capture({ timeoutMs, outPath })

Raw single capture with no enrollment/matching — useful for a "test the reader" diagnostic, or feeding your own matching pipeline.

Events

  • waiting — emitted right before each blocking capture call; this is your cue to show "place your finger now" in a UI.
  • sample — { sample, total }, emitted during enroll() before each of its (up to numSamples) captures.
  • captured — { previewPath, width, height, imagePng, imageDataUrl }, emitted after every capture (including each one during enrollment). imagePng is a Buffer; imageDataUrl is ready to drop into an <img> tag.

Finger position constants

FINGERS.RIGHT_THUMB, RIGHT_INDEX, RIGHT_MIDDLE, RIGHT_RING, RIGHT_LITTLE, LEFT_THUMB, LEFT_INDEX, LEFT_MIDDLE, LEFT_RING, LEFT_LITTLE, UNKNOWN. Enrolling different fingers for the same userId are independent templates (<userId>__<finger>.fmd), so one user can enroll multiple fingers as backups.

Source

Full source, the native CLI helper it's built on, and the story of how this was built: https://github.com/msaikens/printCatcher