CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-fingerprintjs--fingerprintjs

Browser fingerprinting library with the highest accuracy and stability for generating unique visitor identifiers

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

components.mddocs/

Component Analysis

Low-level utilities for working with entropy components and generating custom fingerprints from collected browser characteristics.

Capabilities

Hash Components

Converts a dictionary of entropy components into a short hash string (visitor identifier).

/**
 * Converts a dictionary of components into a short hash string
 * Designed for extending the library with custom components
 * @param components - Dictionary of entropy components
 * @returns Hashed visitor identifier string
 */
function hashComponents(components: UnknownComponents): string;

Usage Examples:

import { hashComponents } from '@fingerprintjs/fingerprintjs';

// Hash standard components from get() result
const fp = await FingerprintJS.load();
const result = await fp.get();
const customHash = hashComponents(result.components);

// Hash custom component set
const customComponents = {
  userAgent: { value: navigator.userAgent, duration: 1 },
  language: { value: navigator.language, duration: 0 },
  timezone: { value: Intl.DateTimeFormat().resolvedOptions().timeZone, duration: 2 }
};
const customFingerprint = hashComponents(customComponents);

// Create fingerprints from filtered components
const filteredComponents = Object.fromEntries(
  Object.entries(result.components).filter(([name]) => 
    ['canvas', 'webgl', 'audio'].includes(name)
  )
);
const filteredHash = hashComponents(filteredComponents);

Components to Debug String

Converts a dictionary of components into a human-readable debug format.

/**
 * Converts a dictionary of components into human-friendly debug format
 * Useful for debugging and development purposes
 * @param components - Dictionary of entropy components  
 * @returns Human-readable string representation
 */
function componentsToDebugString(components: UnknownComponents): string;

Usage Examples:

import { componentsToDebugString } from '@fingerprintjs/fingerprintjs';

const fp = await FingerprintJS.load();
const result = await fp.get();

// Generate debug output for all components
const debugString = componentsToDebugString(result.components);
console.log('Fingerprint components:');
console.log(debugString);

// Debug specific component subset
const audioComponents = {
  audio: result.components.audio,
  audioBaseLatency: result.components.audioBaseLatency
};
const audioDebug = componentsToDebugString(audioComponents);
console.log('Audio components:', audioDebug);

Custom Component Workflows

Advanced patterns for creating custom fingerprinting workflows using component utilities.

Component Filtering:

import { hashComponents, componentsToDebugString } from '@fingerprintjs/fingerprintjs';

const fp = await FingerprintJS.load();
const result = await fp.get();

// Create privacy-focused fingerprint (exclude fonts, canvas)
const privacyComponents = Object.fromEntries(
  Object.entries(result.components).filter(([name]) => 
    !['fonts', 'canvas', 'domBlockers'].includes(name)
  )
);
const privacyFingerprint = hashComponents(privacyComponents);

// Create performance-focused fingerprint (only fast components)
const fastComponents = Object.fromEntries(
  Object.entries(result.components).filter(([_, component]) => 
    component.duration < 10 // Under 10ms
  )
);
const fastFingerprint = hashComponents(fastComponents);

Component Analysis:

// Analyze component reliability
const result = await fp.get();
const componentStats = Object.entries(result.components).map(([name, component]) => ({
  name,
  success: 'value' in component,
  duration: component.duration,
  hasError: 'error' in component
}));

// Find most reliable components
const reliableComponents = componentStats
  .filter(stat => stat.success && stat.duration < 50)
  .sort((a, b) => a.duration - b.duration);

console.log('Most reliable components:', reliableComponents);

// Debug failed components
const failedComponents = componentStats.filter(stat => !stat.success);
if (failedComponents.length > 0) {
  console.warn('Failed components:', 
    componentsToDebugString(
      Object.fromEntries(
        failedComponents.map(stat => [stat.name, result.components[stat.name]])
      )
    )
  );
}

Custom Hash Generation:

// Generate multiple fingerprint variants
const result = await fp.get();

// Stable fingerprint (hardware-focused)
const stableComponents = ['hardwareConcurrency', 'deviceMemory', 'colorDepth', 'screenResolution'];
const stableHash = hashComponents(
  Object.fromEntries(
    stableComponents.map(name => [name, result.components[name]])
  )
);

// Dynamic fingerprint (behavior-focused)
const dynamicComponents = ['timezone', 'languages', 'platform', 'cookiesEnabled'];
const dynamicHash = hashComponents(
  Object.fromEntries(
    dynamicComponents.map(name => [name, result.components[name]])
  )
);

// Combined approach
const combinedHash = hashComponents({
  stable: { value: stableHash, duration: 0 },
  dynamic: { value: dynamicHash, duration: 0 },
  timestamp: { value: Date.now(), duration: 0 }
});

Integration Patterns

Common patterns for integrating component analysis into applications.

Development and Debugging:

// Development fingerprint analysis
if (process.env.NODE_ENV === 'development') {
  const result = await fp.get();
  
  console.group('Fingerprint Analysis');
  console.log('Visitor ID:', result.visitorId);
  console.log('Confidence:', result.confidence);
  console.log('Components:', componentsToDebugString(result.components));
  
  // Component performance analysis
  const slowComponents = Object.entries(result.components)
    .filter(([_, component]) => component.duration > 100)
    .map(([name, component]) => ({ name, duration: component.duration }));
    
  if (slowComponents.length > 0) {
    console.warn('Slow components:', slowComponents);
  }
  
  console.groupEnd();
}

A/B Testing Fingerprints:

// Test different fingerprinting strategies
const result = await fp.get();

const strategies = {
  full: result.visitorId,
  minimal: hashComponents({
    platform: result.components.platform,
    userAgent: result.components.languages,
    screenResolution: result.components.screenResolution
  }),
  canvas: hashComponents({
    canvas: result.components.canvas,
    webglBasics: result.components.webglBasics,
    fonts: result.components.fonts
  })
};

// Use different strategies based on use case
const fingerprintStrategy = getFingerprintStrategy(); // Your logic
const selectedFingerprint = strategies[fingerprintStrategy];

docs

agent.md

components.md

entropy-sources.md

fingerprinting.md

index.md

tile.json