NanoID Generator
Generate compact, URL-friendly unique IDs with configurable length and alphabet using unbiased randomness
Generating Compact, URL-Friendly Unique IDs with NanoID
NanoID generates short, secure, unique identifiers using unbiased randomness from crypto.getRandomValues(). At just 21 characters by default (compared to UUID's 36), NanoID produces IDs that are URL-safe, require no encoding, and have a collision probability of less than 1 in a billion even after generating 1 million IDs per second for 100 years. The compact format saves bandwidth in URLs, reduces storage in databases, and improves readability in logs while maintaining cryptographic security.
Configure the ID length (2–128 characters), choose from preset alphabets (URL-safe, alphanumeric, hexadecimal, numeric, or custom), and generate one or multiple IDs instantly. The generator uses an unbiased mask technique that ensures perfectly uniform character distribution regardless of alphabet size — no character appears more frequently than others, preventing statistical attacks on the random space. All generation happens client-side using the Web Crypto API.
Alphabet Options and Collision Mathematics
NanoID's configurability lets you balance compactness against collision resistance:
- URL-safe (default, 64 chars):
A-Za-z0-9_-— 21 characters gives ~126 bits of entropy - Alphanumeric (62 chars):
A-Za-z0-9— no special characters, safe for all contexts - Hexadecimal (16 chars):
0-9a-f— compatible with UUID-expecting systems - Numeric (10 chars):
0-9— for systems requiring numeric-only IDs - Custom alphabet: Any character set for domain-specific requirements
Collision probability follows the birthday paradox: with a 64-character alphabet and 21-character length, you need to generate ~1.1 billion IDs before a 50% chance of collision. Adjust length upward for higher-volume systems or downward for human-readable short codes.
Unbiased Random Generation
A naive approach to custom-alphabet random generation introduces bias — if the alphabet size does not evenly divide 256 (byte range), some characters appear more frequently. NanoID solves this with a masking technique:
- Bit masking: Calculate the minimum number of bits needed to represent the alphabet size, then mask random bytes to this range
- Rejection sampling: If the masked value exceeds the alphabet length, discard it and try the next byte — this ensures perfectly uniform distribution
- Batch generation: Request random bytes in batches rather than one at a time for performance
This means a 62-character alphabet (A-Za-z0-9) produces IDs where each character has exactly 1/62 probability — no statistical shortcuts for attackers attempting to predict or brute-force IDs.
When to Use NanoID vs UUID vs ULID
Each ID format serves different use cases:
- NanoID: When you need compact, URL-safe IDs without time ordering — API keys, session tokens, shareable URLs, invite codes, short links
- UUID v4: When you need standardized 128-bit IDs compatible with databases, ORMs, and protocols that expect UUID format
- ULID: When you need sortable IDs with embedded timestamps for database keys where insertion order matters
- UUID v7: When you need both UUID compatibility and time-ordering (RFC 9562 standard)
NanoID wins on compactness and flexibility — a 12-character NanoID with URL-safe alphabet (~72 bits) provides sufficient uniqueness for most application contexts while being 3x shorter than UUID.
Code Examples
NanoID Generation with Different Configurations
import { nanoid, customAlphabet } from 'nanoid';
// Default: 21 chars, URL-safe alphabet
const id = nanoid(); // "V1StGXR8_Z5jdHi6B-myT"
// Custom length
const shortId = nanoid(10); // "IRFa-VaY2b"
// Custom alphabet: only lowercase + digits (for URLs)
const urlId = customAlphabet('abcdefghijklmnopqrstuvwxyz0123456789', 12);
console.log(urlId()); // "a8f3kx9pq2rm"
// Numeric only (for order numbers)
const numericId = customAlphabet('0123456789', 8);
console.log(numericId()); // "48293017"
// Hex (for compatibility with systems expecting hex strings)
const hexId = customAlphabet('0123456789abcdef', 32);
console.log(hexId()); // "4f9a2c8e1b3d7f6a0e5c9d2b8a4f1e3c"
// Collision probability calculator:
// 21 chars × 64-char alphabet = ~126 bits
// At 1000 IDs/second: ~139 years before 1% collision probability Frequently Asked Questions
What is a NanoID and how does it differ from a UUID?
NanoID is a compact, URL-friendly unique identifier generator. Unlike UUID's fixed 36-character hex format, NanoID allows configurable length (2–128 chars) and custom alphabets. A 21-character NanoID with the default URL-safe alphabet provides comparable collision resistance to UUID v4 while being 40% shorter.
How does NanoID avoid modulo bias?
NanoID uses an unbiased mask technique: it creates a bitmask based on the alphabet size (nearest power of 2), generates random bytes, applies the mask, and rejects values outside the alphabet range. This ensures every character has equal probability regardless of alphabet size.
What collision probability does a 21-character NanoID have?
With the default URL-safe alphabet (64 characters) and length 21, a NanoID has 126 bits of entropy — similar to UUID v4's 122 bits. You would need to generate about 1 billion IDs per second for 4 years to have a 1% collision probability.
Is NanoID generation cryptographically secure?
Yes. This tool uses the browser's crypto.getRandomValues() API, which provides cryptographically secure pseudo-random numbers. The random bytes are never exposed directly — they are masked and mapped to the configured alphabet.