1. Repository Overview
nanoid is a minimalist, secure, URL-friendly unique string ID generator for JavaScript. At just 118 bytes (minified), it provides cryptographically strong random IDs using crypto.getRandomValues in both Node.js and browser environments. The default alphabet (A-Za-z0-9_-) produces URL-safe IDs without encoding.
Key features: tiny size, CSPRNG-based security, URL-safe output, customizable alphabets via customAlphabet(), and a non-secure Math.random() fallback for performance-critical non-security contexts. Includes CLI via bin/nanoid.js.
2. Architecture & Design
Utility library architecture with environment-specific entry points:
index.js— Node.js secure implementation with byte pooling optimizationindex.browser.js— Browser implementation usingwindow.cryptonon-secure/index.js— FastMath.random()alternativeurl-alphabet/index.js— Shared default alphabet (A-Za-z0-9_-)bin/nanoid.js— CLI entry point
3. Module Breakdown
- Core modules (
index.js,index.browser.js): Exportnanoid(),customAlphabet(),customRandom(). Use bitwise operations (byte & 63) for efficient alphabet mapping. - Non-secure (
non-secure/index.js): Same API but usesMath.random()— faster, not cryptographically secure. - URL Alphabet (
url-alphabet/index.js): Exports the 64-character URL-safe alphabet string. - CLI (
bin/nanoid.js): Accepts--sizeand--alphabetflags, prints generated ID to stdout.
4. Core Execution Flow
- User calls
nanoid(size?)orcustomAlphabet(alphabet, size)() - Function calculates required random bytes based on alphabet size
- Secure random bytes obtained via
crypto.getRandomValues()(Node.js uses pooledBuffer.allocUnsafe) - Bytes mapped to alphabet indices using bitwise masking (
byte & mask) - Characters concatenated into final ID string and returned
5. API Surface
nanoid(size?: number): string— Generate URL-safe ID (default 21 chars)customAlphabet(alphabet: string, size?: number): () => string— Factory for custom alphabet generatorcustomRandom(random: Function, alphabet: string, size?: number): () => string— Full customization- CLI:
npx nanoid [--size N] [--alphabet CHARS]
6. Key Business Logic
Byte pooling in Node.js (index.js): Pre-allocates a large Buffer of random bytes to minimize crypto.getRandomValues syscalls. Pool refilled when depleted. This is the main performance optimization.
Alphabet mapping uses Math.clz32 to compute optimal bitmask for non-power-of-2 alphabets, with rejection sampling to ensure uniform distribution.
7. Data Flow & State Management
Stateless library — no persistence or external state. Only internal state is the Node.js random byte pool (module-level Buffer). Custom generators use closures to capture configuration.
8. Configuration & Environment
No env vars or config files needed. Automatically detects Node.js vs browser for the appropriate crypto API. Requires ES Module support or compatible bundler.
9. Dependencies & Tech Stack
Zero runtime dependencies. Uses only built-in node:crypto (Node.js) or window.crypto (browser). Dev dependencies include benchmarking tools.
10. Strengths & Weaknesses
Strengths: Extremely small footprint (118B), zero dependencies, secure by default, excellent performance via byte pooling, clean API design.
Weaknesses: No built-in collision detection, limited to single-unit output, non-secure fallback requires explicit opt-in import path.
11. Quick Reference
- Entry:
index.js(Node),index.browser.js(browser),non-secure/index.js(fast) - Default ID length: 21 characters from
A-Za-z0-9_- - Collision probability: ~1 billion IDs needed for 1% chance at default settings
- Byte pool size: 128 × size multiplier in Node.js implementation
- CLI:
bin/nanoid.jswith--sizeand--alphabetoptions