I Built a Cookie-Free Visitor Analytics Platform — Here's What I Learned
TL;DR: I built identity-js, an open-source visitor intelligence platform that uses browser fingerprinting and behavioral analytics to understand how people actually use your site — no cookies, no consent banners. You can try the live demo right now.
The Problem
Every analytics tool I tried fell into one of two camps: either it was a bloated, cookie-dependent behemoth that required consent banners across half the page, or it was a privacy-first counter that told me someone visited but nothing about how they experienced my site.
I wanted something in between. I wanted to know: are visitors frustrated? Are they rage-clicking on something that looks like a button but isn't? Are they abandoning my signup form halfway through? Are bots inflating my numbers?
None of the tools I found answered all of these questions without requiring cookies or a 200KB script.
So I built one.
What identity-js Does
At its core, identity-js is a lightweight tracker (29KB gzipped, zero dependencies) that collects 40+ browser signals and watches for 11 behavioral patterns in real time.
Browser fingerprinting generates a persistent visitor ID from signals like canvas rendering, WebGL parameters, audio context, installed fonts, speech synthesis voices, and math engine quirks. No cookies needed — the ID survives cookie clears and private browsing.
Behavioral tracking is where it gets interesting. The tracker automatically detects:
- Rage clicks — rapid frustrated clicking on the same spot
- Dead clicks — clicks on elements that do nothing
- Phantom clicks — clicks on things that look interactive but aren't
- Form abandonment — forms started but never submitted, including which field they bailed on
- Input hesitation — how long someone stares at a field before typing (a strong signal of confusion)
- Reading behavior — whether someone is actually reading, skimming, or just scrolling past
- Error tracking — JS exceptions and console errors your visitors hit
- Text copying — when users copy text from your pages (great for knowing what content resonates)
All of these feed into a frustration score — a weighted composite that tells you at a glance which visitors are having a bad time on your site.
The Stack (Zero Dependencies on the Server Too)
The whole server runs on pure Node.js with zero npm dependencies. I used Node 22's built-in node:sqlite module for the database, node:crypto for auth (scrypt + HMAC-SHA256 tokens), and built the HTTP routing from scratch.
The dashboard is a single HTML file — no React, no build step, no framework. Just vanilla JS with a hand-rolled router and CSS custom properties for theming. It includes an interactive map (Leaflet), real-time live visitor view, per-visitor drill-downs with full session timelines, and PDF report exports.
The tracker builds to UMD, CJS, and ESM via Webpack, so it works everywhere — script tag, npm import, or require.
import IdentityJS from '@identityjs/tracker';
const visitor = await IdentityJS.init({
apiKey: 'pk_live_YOUR_KEY',
});
// That's it. Fingerprinting + all behavioral tracking starts automatically.
// Want custom events too?
visitor.track('signup_clicked', { plan: 'pro' });
Bot Detection Without ML
One thing I'm particularly happy with is the bot detection system. Instead of relying on machine learning or third-party services, it scores visitors 0–100 based on observable signals: missing browser APIs, headless browser flags, impossible screen configurations, zero-entropy fingerprints, and behavioral patterns (or lack thereof).
A real human browsing your site produces a messy, unique fingerprint with varied interactions. A bot produces clean, predictable signals with mechanical timing. The scoring system catches this reliably, and the dashboard surfaces bot visitors separately so they don't pollute your analytics.
The Live Demo
Rather than asking you to sign up to see if this is useful, I built a live demo that loads the real dashboard with realistic sample data. You can explore visitor profiles, see the frustration scoring in action, browse session timelines, check out the bot detection — everything the real product does, with no account required.
The demo includes 14 sample visitors with varied profiles: different browsers, devices, locations, and behaviors. There's a frustrated user with rage clicks and form abandons, a detected bot with suspicious signals, and regular visitors with realistic browsing patterns.
What I Learned Building This
Browser fingerprinting is more stable than I expected. The combination of canvas, WebGL, audio context, and font enumeration produces remarkably consistent hashes across sessions. The key is using enough signals that any single one changing doesn't break the whole ID.
Behavioral signals are more valuable than pageview counts. Knowing that 40% of visitors rage-click your pricing toggle, or that the average hesitation time on your email field is 8 seconds, tells you more than knowing you had 10,000 visits last month.
Zero-dependency servers are liberating. Not having node_modules means the entire server deploys in seconds, has zero supply chain risk, and is trivial to audit. Node 22's built-in SQLite is surprisingly capable for a single-server analytics product.
Single-file dashboards aren't as crazy as they sound. Yes, the dashboard HTML file is large. But it loads instantly (one request, no waterfall), is trivial to cache, and I never have to debug a webpack config. For an internal tool like this, the tradeoff is worth it.
Try It
- Live Demo — explore the full dashboard with sample data
- Website — landing page and signup
-
npm package —
npm install @identityjs/tracker - GitHub — full source code
The free tier includes 1,000 visitors and 10,000 events/month. If you're building something and want to understand how your visitors actually experience it, give it a shot.
If you have questions or feedback, drop a comment — I'd love to hear what you think.
Top comments (0)