Skip to Content

Last Updated: 3/9/2026


nanoid()

The main function to generate secure, URL-friendly unique IDs.

Signature

function nanoid<Type extends string>(size?: number): Type

Parameters

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 size parameter (default 21)

Examples

Basic Usage

import { nanoid } from 'nanoid' const id = nanoid() console.log(id) //=> "V1StGXR8_Z5jdHi6B-myT" console.log(id.length) //=> 21

Custom 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 GeneratedCollision 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() via node: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

Use CaseSizeEntropyNotes
Default21126 bitsUUID v4 equivalent
Short URLs10-1260-72 bitsCheck collision probability
Security tokens32+192+ bitsExtra security margin
Human codes6-836-48 bitsUse custom alphabet

Calculating Safe Size

Use the collision calculator  with:

  1. Alphabet size: 64 (default)
  2. ID size: Your desired length
  3. 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) // ✅ Correct

See Also