-
Notifications
You must be signed in to change notification settings - Fork 2
Cross-runtime ID generators for Deno, Bun, and Node.js — NanoID, CUID, CUID2, ULID, MongoDB ObjectID, and sequential/simple IDs.
The ID package provides high-performance ID generators optimized for different scenarios: compact URLs (NanoID), distributed systems (ObjectID, ULID), sequential ordering (SequenceID), date-sequential IDs (SimpleID), and collision-resistant IDs with privacy-preserving format (CUID, CUID2). All generators are collision-resistant, cryptographically secure where appropriate, and work seamlessly across Deno, Bun, Node.js, Cloudflare Workers, and browsers — the process-identifier component that ObjectID/SequenceID mix in for cross-process uniqueness degrades to 0 where no process ID is exposed (Workers, browsers), which is documented, not a functional break.
- ✅ Multiple ID formats - Choose the right ID type for your use case
- ✅ High performance - Optimized generators with minimal overhead
- ✅ Collision resistant - Cryptographically secure random generation
- ✅ URL-safe - All IDs work in URLs without encoding
- ✅ Sortable options - Timestamp-based ordering with ULID and SequenceID
- ✅ MongoDB-inspired - ObjectID uses a MongoDB-style layout (not the canonical 24-char hex — see ObjectID docs)
- ✅ Dependency-light - only the
@tundralibs/compatand@tundralibs/utilsworkspace siblings, no third-party runtime deps - ✅ Runtime agnostic - Works on Deno, Bun, Node.js, Cloudflare Workers, and browsers
| Topic | Description |
|---|---|
| NanoID | Compact, URL-safe IDs with custom alphabets |
| ObjectID | MongoDB-inspired mixed-radix identifiers |
| ULID | Sortable, timestamp-based universally unique |
| CUID | Process-sortable 25-char c-prefixed IDs |
| CUID2 | Cryptographically secure, privacy-preserving |
| SequenceID | Sequential IDs with timestamp and counter |
| SimpleID | Date-sequential, human-readable IDs |
| Comparison Guide | Feature comparison and use case recommendations |
| Performance | Benchmarks and optimization tips |
Deno:
deno add @tundralibs/idBun:
bunx jsr add @tundralibs/idNode.js:
npx jsr add @tundralibs/idDirect import (Deno):
import { cuid, cuid2, nanoID, ObjectID, ulid } from 'jsr:@tundralibs/id';import { nanoID } from '@tundralibs/id';
// Default 21-character ID
const id = nanoID();
// => 'g0b30yv24uuo0grjvi6su'
// Custom length
const shortId = nanoID(10);
// => 'ridvgi_4p7'
// Custom alphabet
import { NUMBERS } from '@tundralibs/id';
const numericId = nanoID(8, NUMBERS);
// => '12345678'import { ObjectID } from '@tundralibs/id';
// Create new ObjectID — 26-char mixed-radix string, NOT canonical 24-char hex
const genId = ObjectID();
const id = genId();
// => '65a1b2c3019aB30c1f4q000001'
// Custom starting counter + explicit machine ID (its length widens the ID)
const existing = ObjectID(1000, 'server01');
const serverId = existing();
// => e.g. '65a1b2c3019server010c1f4q001001' (31 chars: the 8-char machine ID)import { monotonicUlid, ulid } from '@tundralibs/id';
// Standard ULID
const id = ulid();
// => '01ARZ3NDEKTSV4RRFFQ69G5FAV'
// Monotonic ULID (guaranteed sort order)
const id1 = monotonicUlid();
const id2 = monotonicUlid();
// id2 > id1 even if generated in same millisecondimport { cuid } from '@tundralibs/id';
const id = cuid();
// => 'clrwk6yt40001qz2ek6f7r2t1'
// Format: c + 8-char timestamp + 4-char counter + 4-char fingerprint + 8 random chars
// IDs minted in the same process sort lexicographically by creation order.import { cuid2 } from '@tundralibs/id';
const id = cuid2(); // 24-char default
// => 'k3rj9xn8q1p7m2w5y6h4t8d9'
const longerId = cuid2(32); // 24..32 supportedUnlike CUID and ULID, CUID2 has no embedded timestamp — minting time can't be reconstructed from the ID. Use for public-facing tokens (magic links, password reset, verification codes).
import { sequenceID } from '@tundralibs/id';
// Create sequential IDs
const seq = sequenceID();
const id1 = seq();
// => 72623859790382856n
const id2 = seq();
// => 72623859790382857nimport { simpleID } from '@tundralibs/id';
// Default date-based ID with counter
const gen = simpleID();
const id = gen();
// => 202412260001n (YYYYMMDDNNNN)
// Custom counter length
const orderGen = simpleID(0, 6);
const orderId = orderGen();
// => 20241226000001n- URLs and public IDs: NanoID (compact, customizable)
- Traceable distributed IDs: ObjectID (embedded timestamp + machine + counter)
- Distributed systems: ULID (sortable, timestamp-based)
-
Process-sortable,
c-prefixed: CUID (25-char, ParallelDrive convention) - Tokens / public IDs where minting time must stay private: CUID2
- Sequential ordering: SequenceID (ordered with counter)
- Date-sequential counters: SimpleID (predictable, human-readable)
See the Comparison Guide for detailed recommendations.
MIT