TL;DR
ClientJS is one of the original open-source fingerprinting libraries: a tiny, readable, Apache-2.0, pure-JavaScript file that folds a basic set of browser properties into a single 32-bit integer. It is genuinely simple, and for low-stakes recognition it still works.
It is also effectively unmaintained, with its last release in 2021, and it predates modern signal techniques. There is no WebGL pixel readback, no WebGPU, no audio fingerprint, no cross-browser identity, and no anti-spoof.
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 recognition, ClientJS is fine. If you need cross-browser matching or anti-fraud, that is Benny.
Architecture: one integer vs two hashes
ClientJS collects a basic set of browser properties (user agent, screen, timezone, language, fonts, plugins, storage flags, and a canvas print) and folds them into a single 32-bit integer. It is fast and tiny, and it does not distinguish signals that depend on the browser from signals that depend on the underlying hardware.
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. Same device, three browsers, three different fingerprint values, but one identical hardwareFingerprint.
A single integer is enough to recognize a returning visitor inside one browser. It cannot tell you that a Chrome visitor and a Safari visitor are the same device. That gap is the difference between simple recognition and cross-browser device matching.
Signal coverage: classic vs modern
ClientJS predates most of the signal techniques that carry entropy today. Its canvas check is a basic print, and it has no WebGL pixel readback, no WebGPU, and no audio fingerprint. The signal set it ships is the signal set you get; it has not changed materially since 2021.
Benny measures what the hardware does: GPU identity and a WebGPU trace, WebGL pixel readback rather than only reported constants, an audio path, and a set of hardware-bound device characteristics that stay stable across browsers. More entropy, and entropy that survives a browser switch.
For coarse, low-stakes recognition, ClientJS's lighter signal set is not a dealbreaker. For distinguishing similar devices or resisting evasion, modern signal coverage matters.
Comparison API: ship it or build it
ClientJS hands you an integer. If you want to ask whether this device is the same as last week's with one changed property, 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.
If you are building anti-fraud, where the question is rarely an exact yes or no and usually how similar two devices are, that comparison logic is the actual product. Benny gives it to you. ClientJS leaves it to you.
Anti-spoof: free vs none
ClientJS has no spoof or tamper detection. It records what the browser reports and hashes it, so a spoofed user agent or an anti-detect browser passes straight through.
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 anti-spoof is part of your use case, ClientJS gives you nothing to build on, and Benny ships it in the box.
Where ClientJS is ahead
Honesty time. ClientJS has real advantages, and pretending otherwise would be obvious.
It is open source and tiny. ClientJS is Apache-2.0 and a single readable, pure-JavaScript file with no runtime dependencies. If you require source-available code you can audit and fork, or you want the smallest possible footprint, ClientJS meets that bar and Benny, being closed-source, does not.
It is proven for simple recognition. It has been deployed for years for coarse visitor recognition and basic analytics. If that is all you need, and you do not need anything added after 2021, it does the job.