@systemix/id

Unique, non-secret identifier generation: UUID v4, UUID v7, ULID, and nanoid-style IDs — all with bias-free, crypto-grade randomness. For secrets and tokens, use @systemix/token instead.

Installation

ts
pnpm add @systemix/id

Basic Usage

ts
import {
  generateId,
  generateUlid,
  generateUuid,
  generateUuidV7,
} from '@systemix/id';

generateId(); // "V1StGXR8_Z5jdHi6B-myT"
generateUlid(); // "01ARZ3NDEKTSV4RRFFQ69G5FAV" — sorts chronologically
generateUuid(); // "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed"

Which one?

GeneratorUse when you need
generateIdShort, URL-safe random IDs (API keys visible in URLs)
generateUuidV7Time-ordered standard UUIDs (best default for new DB primary keys)
generateUlidLexicographically sortable IDs (DB index-friendly)
generateUuidFully random UUIDs; creation time must stay private

Examples

Custom size and alphabet

ts
generateId({ size: 10 });
generateId({ size: 16, alphabet: '0123456789abcdef' });

Monotonic ULIDs

When generating several IDs within the same millisecond (tight loops), the monotonic factory increments the random suffix instead of re-randomizing — output is strictly increasing:

ts
import { createMonotonicUlid } from '@systemix/id';

const nextUlid = createMonotonicUlid();
nextUlid(); // 01ARZ3NDEKTSV4RRFFQ69G5FAW
nextUlid(); // 01ARZ3NDEKTSV4RRFFQ69G5FAX

UUID v7 (time-ordered)

ts
import {
  generateUuidV7,
  createMonotonicUuidV7,
  uuidV7Timestamp,
} from '@systemix/id';

generateUuidV7(); // "018bcfe5-687b-7e4e-93c7-f59b358ffd5b"

// Strictly increasing, even within one millisecond or if the clock steps back:
const next = createMonotonicUuidV7();
next() < next(); // true

uuidV7Timestamp(generateUuidV7(1_700_000_000_123)); // 1700000000123

UUIDv7 (RFC 9562) puts a 48-bit millisecond timestamp first, so new rows land at the end of a B-tree index instead of scattered through it. The timestamp is readable from the ID — use v4 where creation time must stay private.

UUID validation

ts
import { isUuid } from '@systemix/id';

isUuid(value); // validates format, version, and variant
isUuid(value, 4); // must be version 4

Character selection uses rejection sampling on crypto.getRandomValues, so every character is equally likely — no modulo bias.

Try it

Open the ID Generator demo to generate and inspect IDs interactively.