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

@sutraa/mudra

v0.1.0

Published

Hardware-level device fingerprinting for Node.js — a stable machine ID derived from firmware, TPM, and kernel identity signals, with confidence scoring and honest degradation in VMs and containers.

Readme

@sutraa/mudra

mudra (मुद्रा) — seal, signet. A stable machine identity for Node.js, sealed from hardware.

CI npm license

Hardware-level device fingerprinting via a native N-API addon. mudra reads multiple firmware, kernel, and hardware identity signals — DMI/SMBIOS UUIDs and serials, OS machine IDs, disk serials, MAC addresses, TPM / Secure Enclave presence — normalizes them, and hashes them into one stable 256-bit machine ID with a confidence score that tells you how much to trust it.

  • Stable — same ID across runs, reboots, and (by default) NIC/disk swaps.
  • Tamper-resistant, honestly scoped — multiple independent signals hashed together; changing the ID requires changing firmware-level identifiers, not editing a config file. See What this is — and is not.
  • Prebuilt binaries for 8 targets (Linux glibc/musl, macOS, Windows — x64 & arm64) ship inside the package: no compiler needed at install time.
  • Pure-JS fallback — on platforms without a prebuild, installation never fails; the library degrades gracefully and tells you (fingerprint().native === false).
  • VM/container aware — virtualized environments deliberately virtualize hardware identity, so mudra detects them and caps the confidence score instead of pretending.
  • Privacy-conscious — raw serials are never exposed unless you ask (raw: true), and an application salt derives unlinkable per-app IDs via HMAC.

Install

npm install @sutraa/mudra

Quick start

const mudra = require('@sutraa/mudra');
// or: import mudra from '@sutraa/mudra';

const id = await mudra.id();
// '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08'

const fp = await mudra.fingerprint();
// {
//   id: '9f86d081…',
//   confidence: 0.85,
//   virtualized: false,
//   container: false,
//   platform: 'linux',
//   native: true,
//   sources: {
//     os_machine_id:   { available: true,  tier: 'core',     hash: '3c363836cf4e1666' },
//     firmware_uuid:   { available: false, tier: 'core' },          // needs root on Linux
//     firmware_serial: { available: true,  tier: 'core',     hash: '8a331fdde7032f33' },
//     disk_serials:    { available: true,  tier: 'volatile', hash: 'aec070645fe53ee3' },
//     mac_primary:     { available: true,  tier: 'volatile', hash: 'b51d18b551043c1f' },
//     tpm:             { available: true,  tier: 'presence', hash: '0263829989b6fd95' }
//   }
// }

API

| Function | Returns | | |---|---|---| | id(opts?) | Promise<string> | Stable machine ID (64-char hex) | | idSync(opts?) | string | Sync variant | | fingerprint(opts?) | Promise<Fingerprint> | Full structured report | | fingerprintSync(opts?) | Fingerprint | Sync variant |

Options

  • salt?: string — derive the ID with HMAC-SHA-256(salt) instead of plain SHA-256. Two applications using different salts get unlinkable IDs from the same machine. Recommended for anything privacy-adjacent.
  • strict?: boolean — also mix volatile sources (primary MAC, disk serials) into the ID. Binds tighter to the exact hardware configuration, but the ID changes when a NIC or disk is swapped. Default false.
  • raw?: boolean (fingerprint* only) — include raw source values. By default only short per-source hashes are exposed so fingerprints can be logged without leaking serial numbers.

How the ID is built

Each source value is normalized (trimmed, lowercased, vendor placeholder values like To be filled by O.E.M. and all-zero UUIDs rejected), then present core-tier sources are serialized in sorted order and hashed with SHA-256:

mudra/v1
firmware_serial=pf2ab3cd
firmware_uuid=4c4c4544-0042-3510-8043-b7c04f503232
os_machine_id=b08dfa6083e7567a1921a715000001fb

Missing sources are omitted, never hashed as empty — so a source that was unreadable yesterday and unreadable today keeps the ID identical, and the ID only shifts when actual identity changes.

Hardware sources by platform

| Source | Linux | macOS | Windows | Tier | |---|---|---|---|---| | OS machine ID | /etc/machine-id | IOPlatformUUID (IOKit) | MachineGuid (registry, 64-bit view) | core | | Firmware UUID | DMI product_uuid ¹ | — | SMBIOS Type-1 UUID | core | | Firmware serial | DMI product_serial ¹ | IOPlatformSerialNumber | SMBIOS system serial | core | | Disk identity | /dev/disk/by-id | IOKit storage serials | IOCTL_STORAGE_QUERY_PROPERTY | volatile | | Primary MAC | sysfs (physical NICs) | getifaddrs | GetAdaptersAddresses | volatile | | Trusted hardware | TPM 2.0 presence | Secure Enclave presence | TPM via TBS (roadmap) | presence |

¹ Root-only on most kernels; silently absent otherwise (and the ID stays stable either way).

Tiers: core sources form the default ID · volatile sources join it only with strict: true · presence sources never enter the ID — they only raise confidence.

Confidence score

confidence ∈ [0, 1] is the weighted share of the platform's possible sources that produced a usable value, then capped by environment:

  • Running under a hypervisor → capped at 0.5 (the host can clone or forge every identifier below it).
  • Running in a container → capped at 0.25 (the "hardware" identity is largely an image artifact).
  • Pure-JS fallback path → small penalty (it reaches fewer sources than the native addon).

Treat the score as how much this ID means, and pick your own threshold per use case (e.g. license binding might require >= 0.6 && !container).

What this is — and is not

This is a best-effort hardware identity, not a hardware root of trust. Userspace — any userspace, in any language — can read stable hardware identifiers but cannot enforce their immutability:

  • root/admin can change most sources (/etc/machine-id is a file; MachineGuid is a registry value; MACs can be spoofed; even SMBIOS can be rewritten with vendor tools).
  • VMs virtualize everything — the hypervisor decides what UUID and serials the guest sees, and can give two VMs identical identities.
  • Containers share the host kernel but see namespaced, image-supplied identity.

What mudra does give you: an attacker must forge multiple independent identifiers at once (firmware UUID + machine ID + serials) rather than editing one value; casual tampering and copy-paste cloning are detectable; and the confidence score plus virtualized/container flags tell you when the ID is weak instead of lying to you.

Genuine tamper-resistance requires hardware-backed keys — TPM 2.0 attestation and Secure Enclave signing. v0.1 detects those chips and scores their presence; key-backed attestation is the roadmap for the enhanced tier.

Good fits: license binding, device-count enforcement, fraud signals, telemetry dedup, cache keys. Poor fits: sole authentication factor, anything adversarial against a root-level attacker.

Prebuilds & fallback

Prebuilt binaries (N-API 8, so one binary per platform serves all Node ≥ 18) are bundled for:

| | x64 | arm64 | |---|---|---| | Linux (glibc) | ✅ | ✅ | | Linux (musl/Alpine) | ✅ | ✅ | | macOS | ✅ | ✅ | | Windows | ✅ | ✅ |

Anything else: install tries a source compile (needs a C++ toolchain), and if that fails the package still installs and runs on the pure-JS fallback — fewer sources, lower confidence, native: false. Set MUDRA_FORCE_FALLBACK=1 to force the fallback path (useful for testing).

The two paths never disagree about the same hardware, but the native addon reaches more sources than the fallback on some platforms — notably on Windows, where the fallback reads only the OS MachineGuid (no SMBIOS), so its ID and confidence are lower than the native addon's. Callers doing strict hardware binding should require fingerprint().native === true and gate on confidence.

Roadmap

  • TPM 2.0 EK identity — hash of the endorsement key public part as a burned-in, unforgeable source (Linux /dev/tpmrm0, Windows TBS).
  • Secure Enclave–backed keys on macOS for a signing-capable identity.
  • FreeBSD sources (kern.hostuuid).

Contributing

Issues and PRs welcome. Note the toolchain quirk: this repo intentionally has no lockfile and all native builds/tests run in the CI matrix (.github/workflows/prebuild.yml) — there's no need to compile locally to contribute a source module.

Author

Mohsin Rajaportfolio · GitHub · LinkedIn · Instagram

License

MIT