Last Updated: 3/9/2026
nanoid()
The main function to generate secure, URL-friendly unique IDs.
Signature
function nanoid<Type extends string>(size?: number): TypeParameters
size (optional)
- Type:
number - Default:
21 - Range: Any positive integer
- Description: Length of the generated ID in characters
Return Value
- Type:
string - Format: URL-safe characters (
A-Za-z0-9_-) - Length: Specified by
sizeparameter (default 21)
Examples
Basic Usage
import { nanoid } from 'nanoid'
const id = nanoid()
console.log(id) //=> "V1StGXR8_Z5jdHi6B-myT"
console.log(id.length) //=> 21Custom Size
import { nanoid } from 'nanoid'
// Short ID
const shortId = nanoid(10)
console.log(shortId) //=> "IRFa-VaY2b"
// Long ID
const longId = nanoid(32)
console.log(longId) //=> "gB7pQr2nJ8vK4fW9xZ1mT5hL3cN6dY8u"TypeScript with Opaque Types
import { nanoid } from 'nanoid'
// Define branded type
declare const userIdBrand: unique symbol
type UserId = string & { [userIdBrand]: true }
// Explicit type parameter
const userId = nanoid<UserId>()
// Type inference
interface User {
id: UserId
name: string
}
const user: User = {
id: nanoid(), // Automatically inferred as UserId
name: 'Alice'
}Use Cases
Database Primary Keys
import { nanoid } from 'nanoid'
const user = {
id: nanoid(),
email: 'user@example.com',
createdAt: new Date()
}
await db.users.insert(user)URL Slugs
import { nanoid } from 'nanoid'
const article = {
slug: nanoid(),
title: 'Getting Started',
url: `/articles/${nanoid()}`
}Session IDs
import { nanoid } from 'nanoid'
app.post('/login', (req, res) => {
const sessionId = nanoid()
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
maxAge: 86400000 // 24 hours
})
})API Tokens
import { nanoid } from 'nanoid'
// Longer for extra security
const apiKey = nanoid(32)
const refreshToken = nanoid(32)
await db.tokens.insert({
key: apiKey,
userId: user.id,
createdAt: new Date()
})Security
Collision Probability
Default 21-character IDs have ~126 bits of entropy:
| IDs Generated | Collision Probability |
|---|---|
| 1,000 | ~0% |
| 1,000,000 | ~0.0000000000000000000000001% |
| 1,000,000,000 | ~0.00000000000000001% |
| 103 trillion | ~0.0000001% (1 in billion) |
For custom sizes, always check the collision calculator .
Random Generation
nanoid() uses cryptographically secure random generation:
- Node.js:
crypto.getRandomValues()vianode:crypto - Browsers: Web Crypto API
- Source: Hardware random number generator
See Security for details.
Performance
Benchmarks
nanoid() 3,693,964 ops/sec
crypto.randomUUID() 7,619,041 ops/sec (2x faster)
uuid v4 7,436,626 ops/sec (2x faster)Benchmarked on Framework 13 7840U, Fedora 39, Node.js 21.6
When to Use
✅ Use nanoid() when:
- You need URL-safe IDs
- Bundle size matters (118 bytes)
- You want shorter IDs than UUID
✅ Use crypto.randomUUID() when:
- You need maximum performance
- UUID format is required
- Bundle size doesn’t matter
Size Guidelines
Recommended Sizes
| Use Case | Size | Entropy | Notes |
|---|---|---|---|
| Default | 21 | 126 bits | UUID v4 equivalent |
| Short URLs | 10-12 | 60-72 bits | Check collision probability |
| Security tokens | 32+ | 192+ bits | Extra security margin |
| Human codes | 6-8 | 36-48 bits | Use custom alphabet |
Calculating Safe Size
Use the collision calculator with:
- Alphabet size: 64 (default)
- ID size: Your desired length
- IDs generated: Expected total over lifetime
Example:
- 10 characters, 1 billion IDs → ~0.1% collision probability
- 12 characters, 1 billion IDs → ~0.0006% collision probability
Common Mistakes
❌ Don’t use for React keys
// WRONG: Generates new ID every render
function TodoList({ todos }) {
return (
<ul>
{todos.map(todo => (
<li key={nanoid()}> {/* ❌ Bad performance */}
{todo.text}
</li>
))}
</ul>
)
}✅ Use stable IDs from data:
function TodoList({ todos }) {
return (
<ul>
{todos.map(todo => (
<li key={todo.id}> {/* ✅ Stable ID */}
{todo.text}
</li>
))}
</ul>
)
}❌ Don’t reduce size without checking
// WRONG: High collision risk
const id = nanoid(6) // ❌ Only 36 bits of entropy✅ Always verify collision probability:
// CORRECT: Checked calculator first
const id = nanoid(10) // ✅ Acceptable for 1M IDs❌ Don’t store size in variable
// WRONG: Type coercion issue
const size = "10"
const id = nanoid(size) // ❌ Might not work as expected✅ Use number literals or parseInt:
const size = parseInt("10", 10)
const id = nanoid(size) // ✅ CorrectRelated APIs
- customAlphabet() - Custom character set
- customRandom() - Custom random generator
- Non-Secure API - Faster, non-cryptographic variant
See Also
- Quick Start - Basic usage examples
- Security - Cryptographic properties
- Collision Probability - Mathematical analysis