t-tuid
v2.2.0
Published
Tiny, time-linked unique IDs — 16 chars, base62, masked time+seq, zero dependencies.
Maintainers
Readme
tuid
Tiny, time-linked unique IDs — 16 characters, base62, zero dependencies.
npm install t-tuidWhat you get
- 16 chars — shorter than UUID (36) and nanoid (21)
- Time-sortable —
ORDER BY idis chronological, no extracreated_atcolumn needed - Fast — ~2M IDs/sec via a pooled CSPRNG (5x faster than nanoid/uuid)
- Zero dependencies — Node.js >= 14 and all modern browsers
Install
npm install t-tuid
# yarn add t-tuid
# pnpm add t-tuidUsage
// CommonJS
const tuid = require('t-tuid');
// ESM
import tuid from 't-tuid';
import { tuid, tuidTime, tuidCompare, isTuid, tuidRandom, customAlphabet } from 't-tuid';Generate an ID
const id = tuid();
// "V3kQ8mN2pRx4Yw9Z" — 16 base62 charsDatabase primary key
// PostgreSQL
await db.query(
'INSERT INTO orders (id, user_id, total) VALUES ($1, $2, $3)',
[tuid(), userId, total]
);CREATE TABLE orders (
id VARCHAR(16) PRIMARY KEY,
user_id VARCHAR(16) NOT NULL,
total NUMERIC NOT NULL
);
-- Chronological order via primary key — no created_at column needed
SELECT * FROM orders ORDER BY id DESC LIMIT 20;Extract the creation timestamp
import { tuidTime } from 't-tuid';
const id = tuid();
const createdAt = tuidTime(id); // returns a Date object
console.log(createdAt.toISOString()); // "2026-04-25T11:45:39.204Z"Sort chronologically
import { tuidCompare } from 't-tuid';
events.sort((a, b) => tuidCompare(a.id, b.id)); // oldest → newestValidate
import { isTuid } from 't-tuid';
isTuid("V3kQ8mN2pRx4Yw9Z") // true
isTuid("bad") // falsePure random ID (no time structure)
When you need an opaque token with no embedded timestamp — session tokens, API keys, OTP codes:
import { tuidRandom } from 't-tuid';
tuidRandom() // 21-char base62 string (matches nanoid default)
tuidRandom(32) // 32-char base62 string
tuidRandom(8) // 8-char base62 stringUses the same pooled CSPRNG with 6-bit bitmask rejection — no modulo bias.
Custom alphabet
Generate random IDs from any character set:
import { customAlphabet } from 't-tuid';
const nanoid = customAlphabet('0123456789abcdef', 16); // hex IDs
const slug = customAlphabet('abcdefghijklmnopqrstuvwxyz', 10); // lowercase slugs
const pin = customAlphabet('0123456789', 6); // 6-digit PIN
nanoid() // "3a9f1c0d8b2e4f7a"
slug() // "kqvmrjntxp"
pin() // "047291"
pin(4) // override length per call → "8312"Alphabet must be 2–256 characters. Uses bitmask rejection to eliminate modulo bias.
React list keys
Generate the ID when data is created, not inside .map().
// Stamp once at creation time
function addItem(text) {
setItems(prev => [...prev, { id: tuid(), text }]);
}
// Stable key — React only diffs what changed
items.map(item => <li key={item.id}>{item.text}</li>)API
| Function | Returns | Description |
|---|---|---|
| tuid() | string | Generate a unique 16-char base62 ID |
| tuidTime(id) | Date | Extract the creation timestamp — throws on invalid input |
| tuidCompare(a, b) | -1 \| 0 \| 1 | Chronological comparator for .sort() |
| isTuid(id) | boolean | Validate a 16-char base62 tuid |
| tuidRandom(size?) | string | Pure random base62 ID, default 21 chars — no time, no structure |
| customAlphabet(alphabet, size?) | () => string | Returns a generator for random IDs from a custom alphabet |
Comparison
Features
| | t-tuid | nanoid | uuid v4 | |---|---|---|---| | ID length | 16 chars | 21 chars (default) | 36 chars | | Bundle (min+gz) | 1.2 kB | 0.1 kB | 2.7 kB | | Throughput | ~2.1M/s | ~370K/s | ~390K/s | | Time-sortable | yes | no | no | | Timestamp extraction | yes | no | no | | Validate ID | yes | no | no | | Pure random ID | yes | yes | no | | Custom alphabet | yes | yes | no | | Custom length | yes | yes | no | | Zero dependencies | yes | yes | yes | | Browser support | yes | yes | yes |
API surface
| Function | t-tuid | nanoid |
|---|---|---|
| Generate ID | tuid() | nanoid(size?) |
| Pure random ID | tuidRandom(size?) | nanoid(size?) |
| Custom alphabet | customAlphabet(alpha, size?) | customAlphabet(alpha, size) |
| Extract timestamp | tuidTime(id) | — |
| Chronological sort | tuidCompare(a, b) | — |
| Validate format | isTuid(id) | — |
| Custom RNG | — | customRandom(alpha, size, rng) |
Choose t-tuid when the ID needs to carry meaning — creation time, sort order, validation — with no extra columns or lookups.
Choose nanoid when you need a pure random opaque token with a fully custom RNG.
License
MIT
