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

@breacket/time-id

v0.1.0

Published

Deterministic, collision-safe Node.js id generator that is deliberately NOT sortable — short, URL-safe, configurable alphabet per deployment.

Readme

time-id

A deterministic, collision-safe id generator for Node.js — short enough to paste by hand, and deliberately not sortable.

Most time-based id generators (ULID, KSUID, Snowflake-style ids) exist specifically to be sortable — that's their selling point. time-id targets the opposite requirement: ids that don't leak creation order, request volume, or growth rate to whoever sees them, while still guaranteeing — not just statistically hoping — that concurrent calls never collide.

const { id } = require('time-id');

id(); // 'StMdgTwA'
id(); // 'StMdgTwB'
id(); // 'StMdgTwC'

Why not sortable

A sequential or sortable id tells anyone who sees it roughly how many records exist, how fast they're being created, and in what order. That's fine for an internal database key. It's often not fine for anything exposed in a URL, an API response, or a support ticket. time-id still uses a timestamp internally (so uniqueness is deterministic, not probabilistic like a random string), but the default alphabet is not in ASCII order, so the encoded output doesn't sort the way the underlying value does.

Why not just nanoid / uuid / ulid / ksuid?

| | uniqueness | sortable | typical length | alphabet | |---|---|---|---|---| | uuid v4 | probabilistic (birthday bound) | no | 36 chars | fixed | | nanoid | probabilistic | no | 21 chars (configurable) | configurable | | ulid / ksuid | deterministic | yes, by design | 26–27 chars | fixed | | time-id | deterministic | no, by design | ~8–11 chars typically | fully configurable |

If you want sortable ids, use ULID or KSUID — they do that job well. If you want deterministic (not just probabilistic) uniqueness without leaking order or volume, and something short enough to read out loud, that's the gap this fills.

Install

npm install time-id

Quick start

const { id, rawId } = require('time-id');

id();     // 'StLXf1AA'  — string, safe for URLs and filenames
rawId();  // 2049638917632n — the same value as a BigInt, if you want to store it as one

Custom configuration

const { createIdGenerator } = require('time-id');

const gen = createIdGenerator({
  epoch: Date.UTC(2026, 0, 1),
  seqBits: 12,          // more headroom per millisecond than the 10-bit default
  shardBits: 8,         // set >0 only if several processes generate ids at once
  shardId: 3,           // this process/instance's shard number
  onSequenceOverflow: 'throw', // fail loudly instead of blocking under extreme burst
});

gen.nextString();

Recovering the parts of an id

gen.decompose('StLXf1AA');
// { timestamp: 2049638917n, date: 2026-07-18T20:07:00.123Z, shardId: 3n, sequence: 0n }

Using your own alphabet

Every deployment can use a different character mapping. Two services running the same package with two different alphabets produce structurally incompatible-looking ids — someone who sees one service's ids gains no insight into how the other service's ids are built.

const { IdCodec, createIdGenerator } = require('time-id');

const myCodec = IdCodec.shuffled(); // random private ordering, generated once at deploy time
const gen = createIdGenerator({ alphabet: myCodec });

API

  • id() / rawId() — zero-config, ready to use.
  • createIdGenerator(options)TimeId instance.
    • .next()bigint
    • .nextString(opts?)string (opts.pad for fixed-width output)
    • .decompose(id){ timestamp, date, shardId, sequence }
  • IdCodec — the encode/decode layer, usable standalone.
    • new IdCodec(alphabet)
    • IdCodec.shuffled(alphabet?, rng?) — private per-deployment ordering
    • .encode(value, length?), .decode(string)

What this does not do

  • It is not a UUID replacement for interop with systems that expect RFC 4122 UUIDs.
  • It does not coordinate shard ids across processes for you — if you use shardBits, assigning distinct shardIds to each process/instance is on you (env variable, config, orchestrator metadata, etc).
  • Sequence/clock-rollback handling that defaults to 'wait'/'throw' will either briefly block the event loop or throw under genuinely extreme load — pick whichever behavior fits your service.

License

MIT