FingerprintJS is a browser fingerprinting library that generates unique visitor identifiers by analyzing browser attributes and device characteristics. It provides a client-side solution for fraud detection and user identification that persists across incognito/private browsing modes and browser data clearing.
npm install @fingerprintjs/fingerprintjsimport FingerprintJS from '@fingerprintjs/fingerprintjs';For named imports:
import {
load,
Agent,
hashComponents,
componentsToDebugString,
LoadOptions,
GetOptions,
GetResult,
Component,
UnknownComponents,
BuiltinComponents,
Confidence
} from '@fingerprintjs/fingerprintjs';For CommonJS:
const FingerprintJS = require('@fingerprintjs/fingerprintjs');For browser script tag:
<script src="https://openfpcdn.io/fingerprintjs/v4/iife.min.js"></script>
<!-- Access via global FingerprintJS object -->
<script>
// Default export includes load, hashComponents, and componentsToDebugString
const fpPromise = FingerprintJS.load();
</script>import FingerprintJS from '@fingerprintjs/fingerprintjs';
// Initialize the agent at application startup
const fpPromise = FingerprintJS.load();
// Get the visitor identifier when needed
(async () => {
const fp = await fpPromise;
const result = await fp.get();
console.log(result.visitorId);
console.log('Confidence:', result.confidence.score);
})();FingerprintJS is built around several key components:
Agent class handles fingerprint collection and visitor ID generationrequestIdleCallback for performanceCore agent loading functionality for initializing the fingerprinting system with performance optimizations and configuration options.
function load(options?: LoadOptions): Promise<Agent>;
interface LoadOptions {
delayFallback?: number;
debug?: boolean;
}
interface Agent {
get(options?: GetOptions): Promise<GetResult>;
}Visitor identification system that analyzes browser characteristics and generates stable visitor identifiers with confidence assessment.
interface GetResult {
visitorId: string;
confidence: Confidence;
components: UnknownComponents;
version: string;
}
interface Confidence {
score: number;
comment?: string;
}Low-level access to individual entropy components and hash generation utilities for custom fingerprinting workflows and debugging.
function hashComponents(components: UnknownComponents): string;
function componentsToDebugString(components: UnknownComponents): string;Built-in entropy sources for collecting browser and device characteristics across 41 different detection methods.
type UnknownComponents = Record<string, Component<unknown>>;
interface Component<T> {
value: T;
duration: number;
} | {
error: unknown;
duration: number;
}Warning: The following exports are for private usage and may change unexpectedly. Use them at your own risk as they are not covered by semantic versioning.
// Hash function (murmur hash implementation)
const murmurX64Hash128: (input: string) => string;
// Source preparation
function prepareForSources(delayFallback?: number): Promise<void>;
// Individual entropy sources (examples)
function getUnstableAudioFingerprint(): Promise<number>;
function getUnstableCanvasFingerprint(): CanvasFingerprint;
function getUnstableScreenFrame(): ScreenFrame;
function getUnstableScreenResolution(): [number | null, number | null] | undefined;
// WebGL utilities
function getWebGLContext(): WebGLRenderingContext | null;
// Browser detection utilities
function isAndroid(): boolean;
function isTrident(): boolean;
function isEdgeHTML(): boolean;
function isChromium(): boolean;
function isWebKit(): boolean;
function isGecko(): boolean;
function isDesktopWebKit(): boolean;
function isSamsungInternet(): boolean;
// Low-level source loading
interface Source<T> {
(options: SourceOptions): Promise<Component<T>>;
}
interface SourceOptions {
cache: Record<string, unknown>;
debug?: boolean;
}
type SourcesToComponents<T> = {
[K in keyof T]: T[K] extends Source<infer U> ? Component<U> : never;
};
function loadSources<T>(
sources: T,
options: SourceOptions,
excludeList: string[]
): () => Promise<SourcesToComponents<T>>;
// DOM utilities
function withIframe<T>(
action: (iframe: HTMLIFrameElement, iWindow: Window) => T,
initialHtml?: string,
domPollInterval?: number
): Promise<T>;interface LoadOptions {
/**
* Fallback delay for browsers without requestIdleCallback support
* @default 50
*/
delayFallback?: number;
/**
* Whether to print debug messages to the console
* @default false
*/
debug?: boolean;
}
interface GetOptions {
/**
* Whether to print debug messages (deprecated)
* @deprecated Use the debug option of load() instead
*/
debug?: boolean;
}
interface GetResult {
/** The visitor identifier */
visitorId: string;
/** A confidence score that tells how much the agent is sure about the visitor identifier */
confidence: Confidence;
/**
* List of components that has formed the visitor identifier.
* Warning! The type is specific but out of Semantic Versioning
*/
components: BuiltinComponents;
/** The fingerprinting algorithm version */
version: string;
}
interface Agent {
/** Gets the visitor identifier */
get(options?: Readonly<GetOptions>): Promise<GetResult>;
}
interface Confidence {
/**
* A number between 0 and 1 that tells how much the agent is sure about the visitor identifier.
* The higher the number, the higher the chance of the visitor identifier to be true.
*/
score: number;
/** Additional details about the score as a human-readable text */
comment?: string;
}
interface Component<T> {
value: T;
duration: number;
} | {
error: unknown;
duration: number;
}
type UnknownComponents = Record<string, Component<unknown>>;
/**
* List of components from the built-in entropy sources.
* Warning! This type is out of Semantic Versioning, i.e. may have incompatible changes
* within a major version. Use `UnknownComponents` for backward compatibility.
*/
type BuiltinComponents = Record<string, Component<unknown>>;