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

prefid

v1.1.1

Published

Type-safe, prefixed IDs (user_a1b2c3) with zero dependencies.

Readme

prefID

Type-safe, prefixed IDs like user_a1b2c3 for TypeScript & JavaScript — always know what an ID belongs to.

npm version downloads CI minzipped size types dependencies license

📖 Read the full documentation → prefid.vercel.app

prefID generates short, unique IDs that carry a prefix telling you what they belong to — user_a1b2c3, order_9f8e7d. The prefix makes IDs readable in logs, URLs, and your database, and TypeScript understands it, so you can never mix a user ID up with an order ID.

import { id } from "prefid";

id("user"); // => "user_a8Kd0f2bQ1nR7pZ3xW4mT6y"
id("order"); // => "order_9f8e7d6c5b4a3F2e1D0cB9aX"

Sortable IDs

Need IDs that sort by creation time? sortableId puts a time component up front, so a plain string sort is also a chronological sort — the idea behind ULID and UUIDv7, but keeping prefID's prefix and type. Great for database keys, cursors, and correlating logs, without a central sequence:

import { sortableId, getTimestamp, getTimestampOrThrow, getDate } from "prefid";

sortableId("evt"); // => "evt_00VQ5a1k0lBjgjfx6pwYy6WkY"
sortableId("evt"); // => "evt_00VQ5a1mgkWGzAvv93g1bC3yR"  ← later, and sorts after

// IDs created in the same millisecond (or if the clock steps backwards) are
// still strictly increasing — monotonic by default.

// Read the embedded time back out:
getTimestamp("evt_00VQ5a1k0lBjgjfx6pwYy6WkY"); // => 1721600000000 (ms), or undefined if malformed
getTimestampOrThrow("evt_00VQ5a1k…"); // same, but throws on a malformed id instead of returning undefined
getDate("evt_00VQ5a1k…"); // => Date, or undefined if malformed/out of range

Prefer a case-insensitive, unambiguous alphabet (like ULID)? Use the exported BASE32_CROCKFORD preset — it drops the look-alike letters I, L, O, U:

import { createSortableId, BASE32_CROCKFORD } from "prefid";

const eventId = createSortableId({ alphabet: BASE32_CROCKFORD });
eventId("evt"); // => "evt_00VQ5A1K0MBJGJFX6PWYY6WKY" — no 0/O or 1/l confusion

Install

npm install prefid

Features

  • 🏷️ Self-describing — the prefix tells you what an ID is at a glance.
  • 🧠 Type-safeid("user") has the type `user_${string}`, so passing the wrong ID type is a compile error.
  • 🔀 Sortable optionsortableId("evt") embeds a time component so IDs sort chronologically as plain strings (ULID / UUIDv7-style), with no central coordinator.
  • 🟨 JavaScript too — TypeScript is optional. Works the same in plain JS; types are a bonus, not a requirement.
  • 🔒 Secure — the random part uses the platform's cryptographic RNG, never Math.random().
  • 🪶 Zero dependencies — tiny and focused on one job.
  • 🌍 Universal — works in Node 14.18+, browsers, Deno, Bun, and edge runtimes. Ships ESM + CommonJS.

JavaScript or TypeScript

prefID works in plain JavaScript just as well as in TypeScript — the published package is already compiled JavaScript, so there's nothing to compile on your end:

// CommonJS
const { id } = require("prefid");
// or ESM: import { id } from "prefid";

id("user"); // "user_a8Kd0f2bQ1nR7pZ3xW4mT6y"

Everything (id, createId, template, ensureUnique, isId, getPrefix, parseId) runs identically in JS. TypeScript users get one extra thing on top — the typed prefix (`user_${string}`) that catches wrong-ID mistakes at compile time. JS users still get editor autocomplete from the bundled type definitions.

Compatibility

prefid runs anywhere with a cryptographic RNG, and picks the right source automatically:

| Runtime | Random source | | --- | --- | | Node.js 14.18+ (ESM + CommonJS) | node:crypto | | Browsers, Deno, Bun, edge runtimes | globalThis.crypto |

Node 14.18 is the minimum because it's the first release with require("node:crypto"). On Node ESM versions that don't expose a global crypto (14–19), a Node-specific entry point (selected automatically via the package's exports conditions) sources randomness from node:crypto — so ESM works there too.

Documentation

Full guides, examples, and the complete API live on the documentation site:

| Guide | | | --- | --- | | Quick Start | Generate your first ID | | id() | The default generator | | createId() | Configure size, separator, alphabet | | sortableId() | Time-ordered IDs (ULID / UUIDv7-style) | | getTimestamp() & getDate() | Read the time back out of a sortable ID (getTimestampOrThrow for a strict variant) | | template() | Custom ID layouts (INV-####-####) | | ensureUnique() | Guarantee an ID is free in your store | | isId(), getPrefix() & parseId() | Validate and read IDs (parseId strictly validates a non-empty body; isId is a loose prefix check) | | Uniqueness & Collisions | How safe the IDs are | | Comparison | vs uuid and nanoid |

Contributing

Contributions are welcome! See CONTRIBUTING.md to get started.

License

MIT © Syed Suhail Ahmed