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

@identityjs/tracker

v1.3.6

Published

Visitor fingerprinting, identification & analytics — drop-in script or npm package

Readme

identity-js

npm version npm downloads bundle size license

Open-source visitor intelligence for modern web apps. Drop-in analytics with browser fingerprinting, behavioral tracking, and real-time insights — no cookies, no consent banners, zero dependencies.

Dashboard & Docs · Live Demo · Get API Key


Why identity-js?

Most analytics tools tell you what happened. Identity-js tells you who did it and how frustrated they were.

| | identity-js | Google Analytics | Hotjar | Microsoft Clarity | |---|:---:|:---:|:---:|:---:| | Cookie-free tracking | Yes | No | No | No | | Browser fingerprinting (40+ signals) | Yes | No | No | No | | Frustration scoring | Yes | No | Yes | Partial | | Rage / dead / phantom click detection | Yes | No | Partial | Yes | | Bot detection with scoring | Yes | No | No | Yes | | Persistent ID (survives cookie clears) | Yes | No | No | No | | Form abandonment tracking | Yes | No | Yes | No | | Real-time visitor dashboard | Yes | Delayed | No | Delayed | | Self-hostable | Yes | No | No | No | | No consent banner needed | Yes | No | No | No | | Bundle size | 45 KB | 90 KB+ | 80 KB+ | 60 KB+ | | Free tier | Generous | Limited | Limited | Unlimited |


Quick start

npm

npm install @identityjs/tracker
import IdentityJS from '@identityjs/tracker';

const visitor = await IdentityJS.init({
  apiKey: 'pk_live_YOUR_KEY',
});

console.log(visitor.visitorId); // "a3f2b1c4d5e6-k9m2"

Script tag

<script src="https://cdn.jsdelivr.net/npm/@identityjs/tracker/dist/identity.min.js"></script>
<script>
  IdentityJS.init({ apiKey: 'pk_live_YOUR_KEY' });
</script>

That's it. Pageviews, sessions, fingerprints, behavioral tracking — all automatic.

Get your API key at identity-js.com/dashboard.


Framework examples

React

import { useEffect } from 'react';
import IdentityJS from '@identityjs/tracker';

function App() {
  useEffect(() => {
    IdentityJS.init({
      apiKey: process.env.REACT_APP_IDENTITY_KEY,
      onReady: (v) => console.log('Visitor:', v.visitorId),
    });
  }, []);

  return <div />;
}

Next.js

// app/layout.js or pages/_app.js
import IdentityJS from '@identityjs/tracker';

if (typeof window !== 'undefined') {
  IdentityJS.init({ apiKey: process.env.NEXT_PUBLIC_IDENTITY_KEY });
}

Gatsby

// gatsby-browser.js
import IdentityJS from '@identityjs/tracker';

export const onClientEntry = () => {
  IdentityJS.init({ apiKey: 'pk_live_YOUR_KEY' });
};

Vue / Nuxt

// plugins/identity.client.js
import IdentityJS from '@identityjs/tracker';

export default defineNuxtPlugin(() => {
  IdentityJS.init({ apiKey: 'pk_live_YOUR_KEY' });
});

Svelte / SvelteKit

// src/routes/+layout.svelte
<script>
  import { onMount } from 'svelte';
  import IdentityJS from '@identityjs/tracker';

  onMount(() => {
    IdentityJS.init({ apiKey: 'pk_live_YOUR_KEY' });
  });
</script>

Plain HTML / WordPress

<!-- Add before </head> -->
<script defer src="https://cdn.jsdelivr.net/npm/@identityjs/tracker/dist/identity.min.js"
  data-api-key="pk_live_YOUR_KEY"></script>

What gets tracked automatically

Once you call init(), everything below starts working with zero configuration:

| Tracker | What it detects | |---|---| | Fingerprinting | 40+ browser signals — canvas, WebGL, audio, fonts, speech voices, math quirks, screen, CPU, timezone | | Dead Clicks | Clicks on non-interactive elements (nothing happened) | | Phantom Clicks | Clicks on elements that look clickable but aren't (pointer cursor, underline, hover effect) | | Rage Clicks | Rapid frustrated clicking on the same element | | Form Abandonment | Forms started but never submitted — which field they stopped at | | Input Hesitation | Time between focusing a field and first keystroke (confusion signal) | | Reading Behavior | Scroll velocity classified as reading, skimming, or scanning per page | | Frustration Score | 0-100 weighted composite: rage clicks (30), dead clicks (15), errors (15), form abandons (20), rapid nav (20) | | Error Tracking | JS exceptions, promise rejections, console errors — with severity classification (error vs warning) | | Text Copy | When users copy text from your page | | Bot Detection | 0-100 bot score with specific detection reasons |


API

IdentityJS.init(options?)

Returns Promise<VisitorObject>.

| Option | Type | Default | Description | |---|---|---|---| | apiKey | string | — | Project API key (pk_live_...) from your dashboard | | endpoint | string | https://www.identity-js.com/api/ping | API endpoint | | onReady | function | — | Called with the visitor object once ready | | trackBehavior | boolean | true | Track clicks, scrolls, keystrokes | | trackSpaNavigation | boolean | true | Auto-track SPA route changes | | sendOnLoad | boolean | true | Send fingerprint on page load | | sendOnUnload | boolean | true | Send session data on page close | | requireConsent | boolean | false | If true, no data sent until grantConsent() is called |

VisitorObject

{
  visitorId: string;        // Persistent ID (survives cookie clears)
  sessionId: string;        // Per-tab session ID
  isNewVisitor: boolean;    // True on first ever visit
  fingerprintHash: string;  // Stable hash of browser signals
  signals: object;          // Full fingerprint signal set

  track(name, data?): void;    // Send custom event
  getBehavior(): object;       // Live behavioral snapshot
  flush(): void;               // Force-send buffered data
  destroy(): void;             // Remove all event listeners
  grantConsent(): void;        // Start sending (consent mode)
  revokeConsent(): void;       // Stop sending, clear buffers
  hasConsent(): boolean;       // Check consent state
}

Custom events

// Queue-safe — works even before init() resolves
IdentityJS.track('added_to_cart', { productId: 'abc', price: 29.99 });

// Or use the visitor object
const visitor = await IdentityJS.init({ apiKey: 'pk_live_...' });
visitor.track('purchase_clicked', { plan: 'pro', price: 49 });

Consent mode

Works with Cookiebot, OneTrust, CookieYes, or any consent manager. The tracker buffers data in memory and sends nothing until the user accepts.

await IdentityJS.init({ apiKey: 'pk_live_YOUR_KEY', requireConsent: true });

// Cookiebot example:
window.addEventListener('CookiebotOnAccept', () => {
  if (Cookiebot.consent.statistics) IdentityJS.grantConsent();
});
window.addEventListener('CookiebotOnDecline', () => {
  IdentityJS.revokeConsent();
});

How it works

  1. Fingerprinting — Collects 40+ passive browser signals (canvas rendering, WebGL renderer, audio context, installed fonts, math precision quirks, etc.) and hashes them into a stable visitor ID that persists even after cookie clears.

  2. Session tracking — Each tab gets a unique session ID. Heartbeats track active time, page changes, and scroll depth. SPA navigations are detected automatically via pushState/popstate.

  3. Behavioral analysis — Click, scroll, and keystroke patterns are analyzed in real-time. Frustrated users trigger rage click, dead click, and form abandonment events that feed into the frustration score.

  4. Bot detection — A weighted scoring system analyzes UA patterns, browser capabilities, and client-side signals. Real social app WebViews (Instagram, Facebook, Viber) are distinguished from unfurler bots.

  5. Privacy-first — No cookies are set. No PII is collected. The fingerprint is a one-way hash. Works without consent banners under most GDPR interpretations for legitimate interest analytics.


License

MIT — use it however you want.


Built by Kontex · Dashboard · Live Demo · GitHub