Skip to content

Collectors

Neoprint ships with 20 built-in collectors. Each independently gathers a browser signal and reports its entropy and stability.

Built-in Collectors

CollectorSignalsEntropyStability
canvas2D rendering, gradients, emoji~10 bits0.85
webglGPU vendor/renderer, extensions, limits~12 bits0.95
audioOfflineAudioContext oscillator~8 bits0.80
fonts48 font families via measureText~12 bits0.90
screenResolution, DPR, HDR, color gamut~6 bits0.70
navigatorUA, platform, languages, memory~8 bits0.75
timingTimer precision, timezone~5 bits0.60
mediaVideo/audio codec support~7 bits0.85
storageStorage availability, quota~4 bits0.60
networkConnection type, RTT, downlink~3 bits0.30
gpuWebGPU adapter info, features~10 bits0.90
mathMath function precision (22 ops)~6 bits0.95
intlLocale, timezone, numbering system~5 bits0.85
cssFeaturesCSS.supports() for 20 features~4 bits0.80
permissionsPermission states for 14 APIs~5 bits0.65
speechAvailable TTS voices~10 bits0.90
domRectgetBoundingClientRect precision~6 bits0.75
svgSVG rendering + text BBox~7 bits0.80
webrtcICE candidate types~4 bits0.50
hardwarePerfCPU micro-benchmarks (float, trig, sort, matrix)~4 bits0.50

Total: ~135+ bits of entropy — enough to uniquely identify >1 billion devices.

Selecting Collectors

ts
// Use all (default)
const fp = await neoprint.get()

// Use specific collectors
const fp = await neoprint.get({
  collectors: ['canvas', 'webgl', 'math', 'fonts']
})

// Privacy mode — excludes invasive collectors
const fp = await neoprint.get({ mode: 'privacy' })

// Incognito-resistant — excludes volatile collectors
const fp = await neoprint.get({ mode: 'incognito-resistant' })

Custom Collectors

ts
neoprint.register('mySignal', {
  async collect() {
    const value = await getMyCustomData()
    return { value, entropy: 5 }
  },
  stability: 0.8,
})

See the Plugin System guide for details.

Released under the MIT License.