Skip to content

Device Fingerprinting: 5 Signals You Can Trust

Device Fingerprinting: 5 Signals You Can Trust

A fraud team asks for one thing: tell me whether this visitor is the same person who paid last week. Device fingerprinting answers with a score, and the difference between a useful answer and a harmful one is which signals enter the identity and which stay in the report.

Code: Fingerprint-JS, MIT licensed.

@globus.studio/fingerprintjs runs in the browser, collects signals, and separates the stable identifier from the evidence around it.

Signal set 1: the stable core

Runtime, locale, display and hardware signals: browser family, client hints, language, timezone, screen metrics, concurrency, touch support, architecture.

These change rarely and slowly. They form the visitorId, and stability is the reason they are chosen: an identifier that moves every week is useless for a returning customer.

Signal set 2: the evidence, kept out of the hash

Bot evidence, private-mode likelihood, tamper evidence, network type, storage capabilities, payment availability, DOM blocker checks. Each is returned with a verdict, a score and the reasons behind it.

None of it enters visitorId by default, and hashComponents() follows the same rule. A bot signal that changed the identifier would give the same person two identities the moment their browser updated a detection method.

Signal set 3: consistency between claims

Tamper evidence compares what the browser claims with what it does: a patched native API, a platform that disagrees with client hints, zero screen dimensions, an empty Chromium global.

Reported, not enforced. The backend decides whether a patched canvas.toDataURL is a privacy extension or a scraper, and it has context the page does not.

Signal set 4: the server’s own view

@globus.studio/fingerprintjs/server recomputes the hash, checks a replay token and adds network risk from the server side. A browser cannot see its own IP reputation, and a client that lies about its signals cannot lie about the address it connects from.

That split is the strongest part of the design. Client signals are evidence; server checks are constraints.

Signal set 5: confidence, as a number

Collection confidence reports how much of the allowed collector set succeeded, and identity confidence adjusts for platform stability. A result with half the collectors blocked is a result with a lower score, not a result with a wrong identifier.

Reporting confidence is unusual and it is the honest choice. A fingerprint taken in a privacy-hardened browser is weaker, and the caller should know before acting on it.

What stays out

A fingerprint must not be the only factor for authentication or blocking. Mobile networks change addresses, VPNs are normal, and a browser update can move a signal overnight.

The readme of the server library says the same thing in its own words, and the two statements agree, which is the sign that the limit is understood by the authors rather than added by a lawyer.

What a team asks first

Will the same customer be recognised next month? The honest answer is “probably, if the device and browser are stable”, and the confidence score tells the caller how much weight that answer carries.

The second question is what happens to the identifier after a browser update. It moves, so the application needs a matching level with a tolerance, not an equality check.

What it costs

A browser bundle under 65 KB, no runtime dependencies, no network calls by default, and a test suite that runs in Chromium, Firefox and WebKit at 100% coverage.

For a product, the cost is the privacy review: a fingerprint is pseudonymous personal data, and the profile choice belongs in that document. A strict profile with a clear retention rule is a defensible position; a maximum collection with no record is not.

Related: server side fingerprinting for the PHP half, and PHP development for how the integration is scoped.