नामाङ्क · NODE 14+ · BROWSER · TYPESCRIPT

@code_with_sachin/uusid

Ultra Unique Secure ID generator — sortable, prefixed, encrypted, hierarchical. Zero dependencies.

INSTALL

BASH
npm i @code_with_sachin/uusid

Why

A UUID tells you nothing except that it is unique. UUSID keeps the uniqueness and adds the things you end up bolting on anyway: the creation time is inside the ID, batches sort naturally so they index well as primary keys, and the same generator hands you a short base32 form, a URL-safe form, a prefixed form, an encrypted form, or a deterministic one derived from content.

  • Zero dependencies, ISC, TypeScript types included.
  • Separate Node and browser builds — the browser one is backed by Web Crypto, so it works in a service worker or an edge runtime without a polyfill.
  • Timestamps, validation and analysis without a database round-trip.

Quick start

TS
import { uusid, uusidBatch, validate } from '@code_with_sachin/uusid';

uusid();          // '3fea9660-9402-11f1-b3c1-518494554557'
uusidBatch(3);    // three of them, generated in one pass
validate(id);     // { valid, isValid, version, entropy }

Playground

Running the real package in your browser, from the /browser entry.

FORMAT

Entry points

Three of them. The browser build swaps Node's crypto for Web Crypto, which makes a few methods async — that is the only API difference worth remembering.

TS
// Node — full surface, including WorkerPool and sync crypto.
const { uusid, createWorkerPool } = require('@code_with_sachin/uusid');

// Explicit server entry (same as the default).
import { uusid } from '@code_with_sachin/uusid/server';

// Browser — ESM, backed by Web Crypto. encrypt/decrypt/fromContent are async
// here because crypto.subtle is, and WorkerPool is not exported.
import { uusid } from '@code_with_sachin/uusid/browser';

API

TOP-LEVEL FUNCTIONS

NAMETYPEDEFAULTNOTES
uusid()() => stringOne ID from the default generator.
uusidBatch(count)(number) => string[]Many in one pass.
base32() / urlSafe() / compact()() => stringAlternate encodings of the same ID space.
hierarchical(options?)(HierarchicalOptions) => stringDotted parent→child ID. `levels`, `separator`, `parent`.
fromContent(content, options?)(string, ContentOptions) => Promise<string>Deterministic, content-derived. Async in the browser entry.
validate(id, options?)(string, ValidationOptions) => ValidationResultReturns valid, version and an entropy measure.
extractTimestamp(id)(string) => numberMilliseconds since epoch, read straight out of the ID.
isInTimeRange(id, start, end)(string, Date|string, Date|string) => booleanRange check without parsing a date column.
analyze(ids)(string[]) => AnalysisResultTotals, duplicates, time range and format breakdown.
getMetrics() / healthCheck()() => Metrics | Promise<HealthCheck>Throughput counters and a self-check.

GENERATORS

NAMETYPEDEFAULTNOTES
createGenerator(options?)(UUSIDGeneratorOptions) => UUSIDGeneratornodeId, clockSeq, prefix, separator, validAfter, validBefore, secretKey.
createPrefixedGenerator(prefix, options?)(string, options) => PrefixedGeneratorEvery ID carries the prefix — user_, order_, and so on.
createEncryptedGenerator({ secretKey })(options) => EncryptedGeneratorgenerate() returns an encrypted ID. Async in the browser.
createWorkerPool(options?)(WorkerPoolOptions) => WorkerPoolNode only. Spreads high-volume generation across workers.
generateSortedBatch(count)(number) => string[]Batch that sorts naturally by creation time.
parseHierarchy(id, options?)(string) => HierarchyInfodepth, parts, parent, root, leaf.

Recipes

Each one is live — the output below the code is generated on this page.

Formats from one generator

ENCODINGS

Same ID space, four presentations. base32 is the one to reach for in a URL a human might type; compact suits opaque keys.

TS
import { createGenerator } from '@code_with_sachin/uusid/browser';

const gen = createGenerator({ prefix: 'user', separator: '-' });

gen.generate();            // prefixed, standard layout
gen.base32();              // 'H7VJMYEUAII7DM6CKGCJIVKFK4' — shorter, case-insensitive
gen.urlSafe();             // no separators, safe in a path segment
gen.compact();             // separators stripped
gen.withSeparator('_');    // same ID, different joint (Node entry)

Sortable by creation time

ORDERING

A sorted batch comes out in generation order, so it indexes well as a primary key — and the timestamp is readable straight back out of the ID.

TS
// Sorted batches come out in generation order, so they index well
// as primary keys — no extra created_at column just to sort by.
const ids = gen.generateSortedBatch(1000);

extractTimestamp(ids[0]);                 // ms since epoch
isInTimeRange(ids[0], start, end);        // cheap range check, no DB round-trip

Hierarchical IDs

PARENT → CHILD

A dotted ID that carries its own ancestry. parseHierarchy reads depth, parts, root and leaf back out — handy for tenant → org → record trees.

TS
import { hierarchical } from '@code_with_sachin/uusid/browser';

const child = hierarchical({ levels: 3 });
// '3feabd7094.0211f1b3c3.518494554557'

gen.parseHierarchy(child);
// { depth, parts, parent, root, leaf }

Deterministic from content

CONTENT-ADDRESSED

The same input always produces the same ID. Use it as a dedupe key or a cache address — no lookup table required.

TS
// Deterministic: the same content always yields the same ID.
// Useful for dedupe keys and content-addressed caches.
const a = await fromContent('invoice-2026-08-001');
const b = await fromContent('invoice-2026-08-001');
a === b; // true

// Async in the browser (crypto.subtle.digest); sync on the Node entry.

Encrypted IDs

AES-GCM

An encrypted generator hands out ciphertext instead of a raw ID, so an identifier leaking from a URL tells an attacker nothing about ordering or volume.

TS
import { createEncryptedGenerator } from '@code_with_sachin/uusid/browser';

const gen = createEncryptedGenerator({ secretKey: process.env.ID_SECRET! });

const id = await gen.generate();        // AES-GCM encrypted, async in browser
const plain = await gen.decrypt(id);