npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lightningresearch/sdk

v1.2.1

Published

Lightning Research Device Intelligence SDK

Readme

@lightningresearch/sdk

Device intelligence SDK for Lightning Research. Identifies devices with a stable fingerprint ID, detects bots, assesses threats, and provides network intelligence — all from the browser.

Installation

npm / yarn / pnpm

npm install @lightningresearch/sdk

The npm package ships the module builds only. The browser <script> bundle is hosted separately and should be loaded from the public SDK URL below.

The runtime sdkVersion is derived from the package metadata at build time, so the shipped client and the package version stay aligned.

CDN (script tag)

<script src="https://lrdefender.lightningresearch.ai/sdk/v1/lr.min.js"></script>

For Subresource Integrity (recommended):

<script
  src="https://lrdefender.lightningresearch.ai/sdk/v1/lr.min.js"
  integrity="sha384-<HASH>"
  crossorigin="anonymous"
></script>

The current SRI hash is published with each release. Contact your account manager or check the deploy logs for the latest integrity value.

The CDN build exposes window.LightningResearchSDK.LightningResearch.


Quick Start

npm (ES modules / CommonJS)

import { LightningResearch } from '@lightningresearch/sdk';

const lr = new LightningResearch({ sessionToken: 'short-lived-session-token' });
const result = await lr.identify();
console.log(result.deviceId, result.confidence, result.risk.level);

CDN

<script src="https://lrdefender.lightningresearch.ai/sdk/v1/lr.min.js"></script>
<script>
  const lr = new LightningResearchSDK.LightningResearch({ sessionToken: 'short-lived-session-token' });
  lr.identify().then(result => {
    console.log(result.deviceId, result.confidence);
  });
</script>

Configuration

const lr = new LightningResearch({
  apiKey: 'lr_...',           // optional: for server-side secret use only
  sessionToken: 'eyJ...',     // optional: preferred for browser collection
  endpoint: 'https://...',    // optional: custom API endpoint
  region: 'us',               // optional: 'us' | 'eu' | 'auto'
  timeout: 10000,             // optional: request timeout in ms (default 10000)
  signals: {                  // optional: toggle individual signal collectors
    canvas: true,
    audio: true,
    webgl: true,
    webglTasks: true,
    fonts: true,
    domRect: true,
    math: true,
    cssMedia: true,
    storage: true,
    adBlock: true,
    gpuTiming: true,          // high-cost probe, enabled by default
    wasmTiming: true,         // high-cost probe, enabled by default
    webrtc: true,             // local network entropy (hashed, privacy-safe)
  },
  privacy: {                  // optional: GDPR / consent controls
    consentRequired: false,   // if true, identify() throws until setConsent(true)
    respectDoNotTrack: false, // if true, identify() throws when DNT=1
  },
});

Use exactly one browser-facing credential path:

  • sessionToken: preferred for browsers; issue it server-side via POST /api/collector/session
  • apiKey: keep server-side only for direct API usage

If you need to reduce runtime cost, disable gpuTiming and wasmTiming explicitly. They are enabled by default because they materially improve matching fidelity.


API Reference

lr.identify(options?)

Collect the device fingerprint and send it to the server for identification.

const result = await lr.identify({ tag: 'login', linkedId: 'user-123' });

Returns IdentifyResponse:

| Field | Type | Description | |-------|------|-------------| | deviceId | string | Stable device identifier | | confidence | number | Match confidence 0–100 | | matchType | string | How the device was matched | | risk | { level, score, factors } | Risk assessment | | isNewDevice | boolean | Whether this is a first-time device | | visitCount | number | Total visits from this device | | requestId | string | Unique request identifier |


lr.getDevice(deviceId)

Retrieve a previously identified device.

const device = await lr.getDevice('abc123');

Returns DeviceResponse with deviceId, confidence, matchType, visitCount, browserCount, firstSeen, lastSeen, blocked, etc.


lr.startBehavioralTracking()

Start collecting behavioral biometrics (mouse, keyboard, scroll, touch). Call early in the page lifecycle for the best signal coverage. Data is automatically included in identify() and bot.detect().

lr.startBehavioralTracking();

// Later, when done:
lr.stopBehavioralTracking();

lr.bot.detect(fingerprint?, behavioral?)

Run bot detection. If behavioral tracking is active, data is included automatically.

const bot = await lr.bot.detect();
// { isBot: false, botScore: 0.12, detectionMethod: 'behavioral', confidence: 0.95 }

lr.bot.analyzeBehavior(behavioral?)

Analyze behavioral signals (mouse movements, keystrokes, scroll patterns). Uses tracked data automatically if startBehavioralTracking() was called.


lr.threat.assess(ip)

Assess threat level for an IP address.

const threat = await lr.threat.assess('1.2.3.4');
// { threatScore: 85, isProxy: true, isVpn: false, isTor: false, country: 'US' }

lr.threat.lookup(ip)

Look up IP reputation and known threats.

lr.threat.recent(limit?)

Get recent threat events for your tenant.


lr.network.analyze(ip?)

Analyze network characteristics (proxy, VPN, datacenter detection).

lr.network.lookup(ip)

Look up detailed IP intelligence.


lr.analytics.query(params?)

Query device analytics data.

lr.analytics.export(params?)

Export analytics data.


Error Handling

The SDK throws standard Error instances in the following cases:

try {
  const result = await lr.identify();
} catch (err) {
  // err.message will be one of:
  // - 'apiKey or sessionToken is required'  (constructor misconfiguration)
  // - 'endpoint must use HTTPS'             (non-HTTPS endpoint)
  // - 'endpoint must be a valid Lightning Research API host'
  // - 'Consent is required before collecting'
  // - 'Do Not Track is enabled'
  // - 'Authentication failed'               (401/403 from API)
  // - 'Rate limited'                        (429 from API)
  // - 'Request failed (NNN)'                (other HTTP errors)
  console.error('LR SDK error:', err.message);
}

Network failures (DNS, timeout, CORS) propagate as the browser's native TypeError from fetch(). Wrap calls in try/catch for production resilience.


Privacy & Consent

For GDPR, ePrivacy, or CCPA compliance:

const lr = new LightningResearch({
  sessionToken: 'short-lived-session-token',
  privacy: {
    consentRequired: true,
    respectDoNotTrack: true,
  },
});

// identify() will throw until consent is granted
lr.setConsent(true);

// Check consent status
lr.hasConsent(); // true

// Revoke consent
lr.setConsent(false);

You can also disable specific signal collectors:

const lr = new LightningResearch({
  sessionToken: 'short-lived-session-token',
  signals: {
    canvas: false,  // disable canvas fingerprinting
    audio: false,   // disable audio fingerprinting
  },
});

Signals Collected

The SDK v1.2.0 collects 90+ browser signals across 30+ modules for maximum identification accuracy:

| Category | Signals | |----------|---------| | Navigator | userAgent, platform, language, languages, cores, memory, maxTouchPoints, cookieEnabled, doNotTrack, plugins, mimeTypes, userAgentData | | Screen | width, height, colorDepth, pixelDepth, screenAvailWidth, screenAvailHeight, devicePixelRatio, screenOrientation, physicalResolution, zoomDetection | | Canvas | Multi-scene rendering + 3 sub-scene hashes + full Canvas2D engine (V2 hash, extended scenes) | | Audio | OfflineAudioContext fingerprint, 32-bin peaks, impulse response, V2 fingerprint, binned frequency hash | | WebGL | Vendor, renderer, 15+ GPU parameters, extensions, capabilities (webglCaps) | | WebGL Tasks | 22 advanced procedural GPU scenes (textures, geometry, wireframe, projection, curves, multi-model, etc.) | | Fonts | Pixel-width metrics + full font list enumeration via full engine | | DOM Rects | BoundingClientRect + full engine clientRects analysis | | Math | 10 math constant precision tests (acos, acosh, cbrt, cosh, etc.) | | CSS | System fonts, computed style fingerprints | | CSS Media | prefers-color-scheme, reduced-motion, pointer, hover, color-gamut, forced-colors, contrast | | Storage | localStorage, sessionStorage, indexedDB availability | | GPU Timing | DRAWNAPART-style draw-call timing traces (point, triangle, fragment workloads) | | Wasm Timing | Engine-level micro-benchmarks (call overhead, memory, math intrinsics) | | WebRTC | Hashed local candidates + full WebRTC device fingerprint | | Battery | Charging status, level, charge/discharge time | | Lies | API tampering / prototype lie detection across 197+ browser APIs | | Headless | Headless browser and automation detection | | Resistance | Tor, Brave, Firefox, privacy resistance detection | | Features | Browser engine identification (Blink, Gecko, WebKit) | | Window | Window property fingerprint | | Worker | Worker scope cross-validation | | Voices | Speech synthesis voice enumeration | | Media | MIME type and media capabilities fingerprint | | Intl | Internationalization API locale fingerprint | | SVG | SVG rendering fingerprint | | Document | HTML element version detection | | Writing Scripts | Installed writing systems and language scripts | | Console Errors | Console error signature fingerprint | | Bot Detection | Client-side bot detection (headless, automation, puppeteer) | | Behavioral | Mouse dynamics, keystroke timing, scroll patterns, touch gestures (opt-in) | | Other | Timezone, ad blocker, battery, zoom detection, trash/pollution detection |

All module outputs are hashed into serverAssist.hashes for compact, privacy-preserving transmission to the matching server.


TypeScript

Full TypeScript types are included. Key types:

import type {
  LightningResearchOptions,
  IdentifyResponse,
  DeviceResponse,
  BotDetectionResponse,
  ThreatAssessmentResponse,
  ThreatLookupResponse,
  AnalyticsQueryResponse,
  SignalsConfig,
  PrivacyConfig,
} from '@lightningresearch/sdk';

Browser Support

| Browser | Version | |---------|---------| | Chrome | 80+ | | Firefox | 78+ | | Safari | 14+ | | Edge | 80+ | | iOS Safari | 14+ | | Chrome Android | 80+ |


License

See LICENSE for details.