TL;DR
ImprintJS is a minimal, open-source browser fingerprinting library: a lightweight file that collects basic browser attributes (canvas, user agent, screen, plugins, and similar signals) and folds them into a hash. It is easy to understand, has no runtime dependencies, and it does the job for simple per-browser recognition.
It is also a library from an earlier era of fingerprinting with low or no recent maintenance. There is no WebGL pixel readback, no WebGPU, no audio fingerprint, no cross-browser identity, and no anti-spoof or automation-detection layer.
Benny tags every signal as hardware or engine and returns two hashes: a per-browser fingerprint and a deterministic cross-browser hardwareFingerprint, plus a compareFingerprints API with six modes and free anti-spoof scoring. If you need a tiny source-available drop-in for coarse single-browser recognition, ImprintJS is a reasonable choice. If you need cross-browser matching, comparison logic, or spoof detection, that is Benny.
Architecture: one hash vs two
ImprintJS collects a set of browser properties and combines them into a single hash. The approach is intentionally minimal: gather what the browser reports, hash it, hand it back. It does not distinguish between signals that vary with the browser (canvas rendering, math operations, engine quirks) and signals that reflect the underlying hardware (GPU identity, installed fonts, screen geometry).
Benny tags every signal as hardware-bound or engine-bound and produces two hashes: fingerprint for per-browser identity, and hardwareFingerprint for deterministic cross-browser identity. The same device running Chrome, Safari, and Firefox returns three different fingerprint values but one identical hardwareFingerprint.
A single hash is sufficient for recognizing a returning visitor within one browser. It cannot tell you that a Chrome visitor and a Safari visitor are the same physical device. That gap is the difference between simple per-browser recognition and cross-browser device matching.
Signal coverage: classic vs modern
Classic single-browser fingerprinting libraries of this generation typically collect user agent, screen dimensions, timezone, language, installed plugins, and a canvas print. That is a workable signal set for low-entropy environments where device diversity is limited.
Modern device environments are more complex. GPU identity, WebGL pixel readback, WebGPU compute results, and audio path characteristics carry significant entropy and stay stable across browser updates. These signals did not exist in their current form when minimal libraries like ImprintJS were written, and a library with no active maintenance cannot add them.
Benny measures what the hardware does: GPU identity, a WebGPU trace, WebGL pixel readback beyond reported constants, an audio path characteristic, and a set of hardware-bound device signals that remain stable even as browsers update their engine-level noise budgets.
Comparison API: ship it or build it
ImprintJS hands you a hash. If you want to ask whether this device is the same one from last month with a minor property change, or similar enough to count as the same user across browsers, you write that matching logic yourself.
Benny ships compareFingerprints with six modes: exact, cross-browser, hardware-only, engine-only, strict, and lenient. Each returns a weighted similarity score, constraint violations, fuzzy matches on screen and audio attributes, and a numeric diff vector ready for downstream scoring.
For anti-fraud use cases, the question is rarely a hard yes or no. It is usually how similar two device snapshots are, and over what dimensions. Building that matching logic correctly on top of a raw hash is non-trivial work. Benny ships it.
Anti-spoof: free vs none
ImprintJS records what the browser reports and hashes it. There is no consistency checking, no automation detection, and no spoof awareness. A spoofed user agent, a virtual machine with a falsified screen resolution, or an anti-detect browser passes through without any signal to the caller.
Benny runs a rule-based consistency check on every fingerprint result and returns a score, a list of flags, and a spoofLikelihood rating of low, medium, or high. It catches automation attributes, spoofed user agents, anti-detect browser signatures, and claimed-versus-actual hardware mismatches, all in the free tier.
If spoof detection is any part of your use case, ImprintJS gives you nothing to build on. Benny ships it in the box.
Where ImprintJS is ahead
Honesty time. ImprintJS has real advantages and pretending otherwise would be obvious.
It is open source and minimal. ImprintJS is source-available, lightweight, and has no runtime dependencies. If you require code you can audit, fork, or vendor into a security-sensitive project, that bar is met. Benny is closed-source and does not meet that requirement.
It is fine for simple recognition. For coarse, low-stakes per-browser recognition where device diversity is limited and spoof resistance is not required, a minimal library does the job. If that is genuinely all you need, the overhead of a more capable library is not worth it.