Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

device-keygen

yashjk0MIT0.0.1TypeScript support: included

Generate a unique device id for each device

device-keygen, device-key, device-id, browserfingerprint, fingerprinting, jsfingerprint, uniquebrowserid, nodejs, cryptography, fraud-detection, canvas-fingerprinting, audio-fingerprinting, visitor-identifier, identification, reactjs, javascript, typescript

readme

Broprint.js

The world's easiest, smallest and powerful visitor identifier for browsers.

Current NPM version Live Demo CodeSandbox Tweet


Broprint.js generates a deterministic string per browser by combining Audio, Canvas, baseline browser signals and optional WebGL vendor/renderer, then hashes the result with a tiny, fast 53‑bit hash.

Live Demo

⚠ For educational and demonstration purposes only.

✨ Features

  • Minimal bundle size, zero runtime deps
  • Multi-format builds: ESM, CJS, Global (IIFE)
  • Works in modern browsers; graceful fallbacks when signals are blocked
  • Includes TypeScript types

📦 Installation

npm

npm i @rajesh896/broprint.js

Yarn

yarn add @rajesh896/broprint.js

CDN (v2.2.0+)

ESM (modern browsers):

<script type="module">
  import { getCurrentBrowserFingerPrint } from 'https://cdn.jsdelivr.net/npm/@rajesh896/broprint.js@latest/lib/index.mjs';
  getCurrentBrowserFingerPrint().then(fp => console.log('Fingerprint:', fp));
</script>

Classic global (no module support needed):

<script src="https://cdn.jsdelivr.net/npm/@rajesh896/broprint.js@latest/lib/index.global.js"></script>
<script>
  getCurrentBrowserFingerPrint().then(fp => console.log('Fingerprint (global):', fp));
</script>

🚀 Quick Start

ESM (Vite, Next.js, CRA with modules)

import { getCurrentBrowserFingerPrint } from '@rajesh896/broprint.js';

const fp = await getCurrentBrowserFingerPrint();
console.log(fp);

CommonJS (Node-style bundlers)

const { getCurrentBrowserFingerPrint } = require('@rajesh896/broprint.js');

getCurrentBrowserFingerPrint().then(console.log);

React example

import { useEffect, useState } from 'react';
import { getCurrentBrowserFingerPrint } from '@rajesh896/broprint.js';

export default function Component(){
  const [fp, setFp] = useState('');
  useEffect(() => {
    getCurrentBrowserFingerPrint()
      .then(v => setFp(String(v)))
      .catch(() => setFp('ERROR'));
  }, []);
  return <pre>{fp}</pre>;
}

Plain HTML (local install)

<!doctype html>
<html>
  <head><meta charset="utf-8"/><title>Broprint</title></head>
  <body>
    <script type="module">
      import { getCurrentBrowserFingerPrint } from './node_modules/@rajesh896/broprint.js/lib/index.mjs';
      getCurrentBrowserFingerPrint().then(console.log);
    </script>
  </body>
</html>

📚 API

getCurrentBrowserFingerPrint(): Promise<string>

Returns a deterministic string for the current browser instance.

Under the hood, Broprint.js combines:

  • Audio fingerprint (OfflineAudioContext render)
  • Canvas fingerprint (styled text + canvas.toDataURL())
  • Baseline browser signals (UA, platform, vendor, hardware concurrency, device memory, screen width/height/color depth, devicePixelRatio, languages, timezone)
  • WebGL vendor/renderer (when WEBGL_debug_renderer_info is available)

All parts are concatenated and hashed via a compact 53‑bit hash (cyrb53). If the audio path fails, the library falls back to canvas + baseline signals (+ WebGL when available). If canvas is unsupported, a stable string plus baseline signals are used to avoid global collisions.

🔍 How it works

  1. Generate audio entropy using an oscillator + compressor rendered in an OfflineAudioContext, summing a slice of the buffer.
  2. Generate canvas entropy by drawing styled text and reading canvas.toDataURL().
  3. Collect baseline signals and optional WebGL vendor/renderer.
  4. Concatenate and hash to produce a compact, deterministic identifier.

Note: anti‑fingerprinting features (e.g., Brave, Firefox ETP, Safari ITP, extensions) can normalize/obfuscate signals. Broprint.js includes additional entropy to reduce collisions, but uniqueness cannot be guaranteed in all hardened environments.

🌐 Browser support

  • Modern Chromium, Firefox, and Safari
  • Graceful degradation when audio/canvas/WebGL are unavailable
  • Some privacy modes/extensions may change stability or uniqueness

🧰 Troubleshooting

  • Audio context errors: many browsers restrict audio contexts until user interaction; call after a click.
  • Identical outputs: your environment may normalize canvas/audio/WebGL; baseline signals still help differentiate.
  • Types: shipped via lib/index.d.ts.

🛠️ Build & contribute

Library build (root):

npm run build

Example app lives under example/ (Create React App).

PRs and issues welcome.

📄 License

MIT

changelog

Changelog

All notable changes to this project will be documented in this file.

[2.2.0] - 2025-08-11

Added

  • Multi-format build: ESM (index.mjs), CJS (index.js), and global/IIFE (index.global.js).
  • Export map for proper Node/ bundler resolution.
  • Automatic global getCurrentBrowserFingerPrint exposure for classic <script> usage.

Fixed

  • CDN usage now works for both <script type=module> and classic <script> tags.

Docs

  • README updated with new CDN examples and removed outdated crypto-js reference.

[2.1.0] - 2022-05-18

Added

  • Logical conditions added for brave browser
  • Readme file and license updated
  • driver function renamed

[2.0] - 2022-04-22

Added

  • Crypto-js dependency removed
  • encryption and hashing algorithms updated.
  • brave browser gives unique id also.

[1.2.0] - 2022-04-22

Added

  • Package renamed as broprint.js

[1.1.2] - 2022-04-19

Added

  • Deployed to netlify.
  • Better documentation added.

[1.1.1] - 2022-04-06

Added

  • Ts types updated.
  • Readme updated for better documentation and with sandbox example

[1.1.0] - 2022-04-05

Added

  • Typescript support
  • crypto-js encryption

[1.0.1] - 2022-03-03

Added

  • demo added

[1.0.0] - 2022-03-03

Initialized

  • Version upgrade.
  • New types added