Last Updated: 3/9/2026
customAlphabet()
Create a custom ID generator with your own alphabet and default size.
Signature
function customAlphabet<Type extends string>(
alphabet: string,
defaultSize?: number
): (size?: number) => TypeParameters
alphabet (required)
- Type:
string - Constraints: Must be ≤256 characters
- Description: Characters to use for ID generation
defaultSize (optional)
- Type:
number - Default:
21 - Description: Default length of generated IDs
Return Value
Returns a generator function:
(size?: number) => stringThe generator function:
- Accepts optional
sizeparameter (overridesdefaultSize) - Returns a random ID string using the custom alphabet
Examples
Numbers Only
import { customAlphabet } from 'nanoid'
const nanoid = customAlphabet('1234567890', 10)
console.log(nanoid()) //=> "4926581703"
console.log(nanoid()) //=> "8201374650"Hexadecimal
import { customAlphabet } from 'nanoid'
const hexId = customAlphabet('0123456789abcdef', 16)
console.log(hexId()) //=> "4f90d13a42b8c7e1"Uppercase Letters
import { customAlphabet } from 'nanoid'
const upperId = customAlphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 8)
console.log(upperId()) //=> "KXZMRTQP"No Ambiguous Characters
import { customAlphabet } from 'nanoid'
// Remove 0, O, I, l for human-readable codes
const nanoid = customAlphabet('346789ABCDEFGHJKLMNPQRTUVWXY', 8)
console.log(nanoid()) //=> "6RTUVWXY"Override Default Size
import { customAlphabet } from 'nanoid'
const nanoid = customAlphabet('1234567890', 10)
// Use default size
console.log(nanoid()) //=> "4926581703" (10 chars)
// Override size
console.log(nanoid(5)) //=> "48267" (5 chars)
console.log(nanoid(15)) //=> "492658170348267" (15 chars)Use Cases
Human-Readable Codes
import { customAlphabet } from 'nanoid'
// Unambiguous characters for support tickets
const ticketId = customAlphabet('23456789ABCDEFGHJKLMNPQRSTUVWXYZ', 8)
const ticket = {
id: ticketId(), //=> "3KJRT8XY"
subject: 'Login issue',
status: 'open'
}Numeric IDs
import { customAlphabet } from 'nanoid'
const numericId = customAlphabet('0123456789', 12)
const order = {
orderNumber: numericId(), //=> "849201736584"
total: 99.99
}URL-Safe Slugs (Lowercase)
import { customAlphabet } from 'nanoid'
const slug = customAlphabet('abcdefghijklmnopqrstuvwxyz0123456789', 12)
const article = {
slug: slug(), //=> "k3xm9tn2pq7z"
title: 'Getting Started'
}Base32 Encoding
import { customAlphabet } from 'nanoid'
// RFC 4648 Base32 alphabet
const base32Id = customAlphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', 16)
console.log(base32Id()) //=> "3KJRT8XY2MN4PQ7Z"Alphabet Design
Best Practices
✅ Do:
- Use ≤256 characters (security requirement)
- Remove ambiguous characters for human-readable IDs (0/O, 1/I/l)
- Consider case sensitivity of your system
- Test alphabet in your use case (URLs, databases, etc.)
❌ Don’t:
- Use >256 characters (breaks security guarantees)
- Include special characters that need URL encoding
- Use characters that look similar (reduces readability)
Common Alphabets
import { customAlphabet } from 'nanoid'
// Digits only
const digits = '0123456789'
// Lowercase hex
const hex = '0123456789abcdef'
// Alphanumeric (case-insensitive)
const alphanumeric = '0123456789abcdefghijklmnopqrstuvwxyz'
// Alphanumeric (case-sensitive)
const alphanumericMixed = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
// No ambiguous characters
const unambiguous = '346789ABCDEFGHJKLMNPQRTUVWXYabcdefghjkmnpqrtuvwxy'
// Base32 (RFC 4648)
const base32 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'
// Base64 URL-safe
const base64url = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'For more alphabets, see nanoid-dictionary.
Security Considerations
Alphabet Size Limit
⚠️ Must be ≤256 characters:
// ✅ OK: 64 characters
const nanoid = customAlphabet('A-Za-z0-9_-', 21)
// ❌ INSECURE: 300 characters
const nanoid = customAlphabet('...300 chars...', 21) // Breaks security!Alphabets >256 characters compromise the internal random generation algorithm.
Collision Probability
Smaller alphabets increase collision risk:
| Alphabet Size | ID Size | Entropy | IDs for 1% Collision |
|---|---|---|---|
| 10 (digits) | 10 | 33 bits | ~6,000 |
| 16 (hex) | 16 | 64 bits | ~5 billion |
| 32 (base32) | 20 | 100 bits | ~1.2 trillion |
| 64 (default) | 21 | 126 bits | ~2.8 quintillion |
Always use the collision calculator with your alphabet size and expected ID count.
Random Generation
customAlphabet() uses the same secure random generation as nanoid():
- Cryptographically secure
- Hardware random generator
- Uniform distribution (rejection sampling)
Performance
Benchmarks
nanoid() 3,693,964 ops/sec (baseline)
customAlphabet() 2,799,255 ops/sec (24% slower)Slower due to rejection sampling for non-power-of-2 alphabet sizes
Optimization Tips
-
Use power-of-2 alphabet sizes for best performance:
- 2, 4, 8, 16, 32, 64, 128, 256 characters
- No rejection sampling needed
-
Reuse generator function:
// ✅ Good: Create once const nanoid = customAlphabet('0123456789', 10) for (let i = 0; i < 1000; i++) { const id = nanoid() // Fast } // ❌ Bad: Create every time for (let i = 0; i < 1000; i++) { const id = customAlphabet('0123456789', 10)() // Slow }
Non-Secure Variant
For non-cryptographic use cases:
import { customAlphabet } from 'nanoid/non-secure'
const nanoid = customAlphabet('0123456789', 10)
console.log(nanoid()) //=> "4926581703"⚠️ Warning: Uses Math.random() instead of crypto. See Non-Secure API.
Common Mistakes
❌ Don’t exceed 256 characters
// WRONG: Breaks security
const nanoid = customAlphabet('...300 characters...', 21) // ❌❌ Don’t forget to call the returned function
import { customAlphabet } from 'nanoid'
// WRONG: nanoid is the generator function, not an ID
const nanoid = customAlphabet('0123456789', 10)
console.log(nanoid) //=> [Function] ❌
// CORRECT: Call the function to generate ID
const id = nanoid()
console.log(id) //=> "4926581703" ✅❌ Don’t use special characters without testing
// WRONG: May cause issues in URLs
const nanoid = customAlphabet('!@#$%^&*()', 10) // ❌ Needs URL encoding
// CORRECT: Use URL-safe characters
const nanoid = customAlphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_', 10) // ✅Related APIs
- nanoid() - Default URL-safe ID generator
- customRandom() - Custom random generator
- urlAlphabet - Default alphabet constant
See Also
- Custom Alphabets - Design guide
- Collision Probability - Math deep dive
- nanoid-dictionary - Pre-made alphabets