ToolDeck

تولیدکننده NanoID

تولید ID‌های کوچک URL-safe با الفبای قابل تنظیم

الفبا

اندازه

تعداد

برای ایجاد NanoID روی تولید کلیک کنید

What is NanoID?

NanoID is a tiny, fast, URL-safe random ID generator. By default it produces 21-character strings using a 64-character alphabet (A-Za-z0-9_-), providing approximately 126 bits of entropy — comparable to UUID v4's 122 bits but in a shorter string.

NanoID does not embed a timestamp or any structured data. Every ID is purely random, generated from the operating system's cryptographically secure random number generator (crypto.getRandomValues() in browsers, crypto.randomBytes() in Node.js).

NanoID vs UUID v4

NanoID and UUID v4 are both random ID generators backed by a CSPRNG. They differ in format, length, and ecosystem support:

PropertyNanoID (default)UUID v4
FormatURL-safe alphanumeric + _-Hyphenated hexadecimal
Length21 characters (default)36 characters
Entropy~126 bits122 bits
URL-safeYes — no encoding neededYes (with hyphens)
Alphabet64 characters (A-Za-z0-9_-)16 characters (0-9a-f)
DependenciesRequires npm packageNative (crypto.randomUUID)
CustomizableYes — length and alphabetNo
StandardNone (community library)RFC 4122 / RFC 9562

Choose UUID v4 when interoperability with external systems matters — databases with native UUID columns, APIs expecting UUID format, or logging infrastructure that parses UUIDs. Choose NanoID when you want shorter IDs and control the full stack.

Collision Probability by Size

NanoID's collision probability depends on the ID length and the generation rate. The following table uses the default 64-character alphabet:

Size (chars)Possible IDsCollision safety
664~1 in 4.5B — safe for a few thousand IDs
864~1 in 4.5T — safe for millions of IDs
1164~1 in 2.8 quadrillion — safe for billions of IDs
1664~1 in 1.2 × 10^19 — safe for trillions of IDs
2164~1 in 10^30 — safe for 100 billion IDs per day for centuries
3264Comparable to UUID v4 (122 bits)
3636Exceeds UUID v4

The default 21-character size is chosen to match UUID v4's collision resistance (~126 bits) while being 41% shorter. For most applications, 21 characters is the right choice.

Custom Alphabets

NanoID's alphabet is fully customizable. The library accepts any string of unique characters as the alphabet and generates IDs using only those characters:

Numeric onlyA-Za-z0-9_-
Use '0123456789' for IDs that are all digits — useful for SMS codes or PIN-style identifiers.
Lowercase hexA-Za-z0-9
Use '0123456789abcdef' for compact hex strings without the UUID hyphen format.
Human-readable0-9a-f
Exclude visually ambiguous characters (0, O, 1, I, l) for IDs that users may need to type manually.
Custom domain0-9
Use any set of characters appropriate to your application — e.g. only vowels+consonants for pronounceable IDs.

Important: use nanoid/non-secure only for non-security-sensitive applications (e.g. UI element IDs). For any ID that needs to be unguessable, always use the default secure import.

How NanoID Generates Randomness

NanoID uses the operating system's cryptographically secure pseudo-random number generator (CSPRNG). In browsers this is crypto.getRandomValues(); in Node.js it is crypto.randomFillSync(). This is the same entropy source used for TLS session keys — far stronger than Math.random().

Rejection Sampling (Avoiding Modulo Bias)

A naive approach to generating random characters would be: take a random byte (0–255) and compute byte % alphabetSize. This introduces modulo bias — some characters appear slightly more often than others when the alphabet size does not evenly divide 256.

NanoID eliminates this bias using rejection sampling:

  1. Determine the smallest power-of-two mask that covers the alphabet size (e.g. for a 64-char alphabet, the mask is 63 = 0b00111111)
  2. Generate random bytes and apply the mask: byte & mask
  3. If the masked value is within the alphabet range, use it. Otherwise, discard and try again.

This means some random bytes are discarded, but the result is a perfectly uniform distribution over the alphabet — no character is more likely than any other.

How the algorithm works — step by step
// Pure browser — no npm package needed
function generateNanoid(alphabet, size) {
  const mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
  const step = Math.ceil((1.6 * mask * size) / alphabet.length)
  let id = ''
  while (id.length < size) {
    const bytes = crypto.getRandomValues(new Uint8Array(step))
    for (const byte of bytes) {
      const idx = byte & mask
      if (idx < alphabet.length) {
        id += alphabet[idx]
        if (id.length === size) break
      }
    }
  }
  return id
}

const URL_SAFE = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'
generateNanoid(URL_SAFE, 21)  // → "V1StGXR8_Z5jdHi6B-myT"

Environment Support

Browser
Modern browsers (Chrome 37+, Firefox 34+, Safari 7+) — uses crypto.getRandomValues()
Node.js 14+
Node.js 14.18+ — uses crypto.randomFillSync()
Deno
Deno — uses crypto.getRandomValues()
Bun
React Native — uses expo-crypto or react-native-get-random-values polyfill
Edge / Cloudflare Workers
Edge runtimes (Cloudflare Workers, Vercel Edge) — Web Crypto API available
React Native
Bun — native crypto support

Code Examples

JavaScript / TypeScript

JavaScript
// npm i nanoid
import { nanoid } from 'nanoid'
nanoid()          // → "V1StGXR8_Z5jdHi6B-myT" (21 chars, URL-safe)
nanoid(8)         // → "Uakgb_J5" (custom size)

// Custom alphabet
import { customAlphabet } from 'nanoid'
const hexId  = customAlphabet('0123456789abcdef', 16)
hexId()       // → "4f3a1b8c9d2e0f7a"

const numId  = customAlphabet('0123456789', 8)
numId()       // → "30812894"

Browser (CDN)

NanoID can be used directly in the browser via a CDN import. No build step required for quick prototyping.

JavaScript
// Pure browser — no npm package needed
function generateNanoid(alphabet, size) {
  const mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
  const step = Math.ceil((1.6 * mask * size) / alphabet.length)
  let id = ''
  while (id.length < size) {
    const bytes = crypto.getRandomValues(new Uint8Array(step))
    for (const byte of bytes) {
      const idx = byte & mask
      if (idx < alphabet.length) {
        id += alphabet[idx]
        if (id.length === size) break
      }
    }
  }
  return id
}

const URL_SAFE = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'
generateNanoid(URL_SAFE, 21)  // → "V1StGXR8_Z5jdHi6B-myT"

Python

Python
# pip install nanoid
from nanoid import generate

generate()              # → "V1StGXR8_Z5jdHi6B-myT"
generate(size=8)        # → "Uakgb_J5"
generate('0123456789abcdef', 16)  # custom alphabet + size

Node.js (CommonJS)

JavaScript
// Node.js — stdlib only, no npm needed
const { randomFillSync } = require('crypto')

function nanoid(alphabet, size) {
  const mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
  const step = Math.ceil((1.6 * mask * size) / alphabet.length)
  let id = ''
  while (id.length < size) {
    const bytes = randomFillSync(Buffer.alloc(step))
    for (const byte of bytes) {
      const idx = byte & mask
      if (idx < alphabet.length) { id += alphabet[idx]; if (id.length === size) break }
    }
  }
  return id
}

Frequently Asked Questions

Is NanoID cryptographically secure?
Yes — when using the default import, NanoID generates IDs using the OS-level CSPRNG (crypto.getRandomValues in browsers, crypto.randomFillSync in Node.js). This is the same entropy source used for cryptographic key generation. NanoID values are suitable for session tokens, API keys, and other security-sensitive identifiers.
Can I use NanoID as a database primary key?
Yes. NanoID strings are URL-safe and can be stored as CHAR or VARCHAR columns. However, NanoID has no timestamp component, so IDs are not sortable by generation order — this will cause B-tree index fragmentation at high insert rates, similar to UUID v4. For time-ordered primary keys, use ULID or UUID v7 instead.
How does NanoID compare to crypto.randomUUID()?
Both use a CSPRNG and provide strong randomness. crypto.randomUUID() is native (no dependency), produces 36-character hyphenated UUID v4 strings, and is universally recognized by databases and APIs. NanoID requires an npm package but produces shorter strings (21 chars default) with a customizable alphabet. For most cases, prefer crypto.randomUUID() to avoid a dependency.
What happens if I use a very short NanoID?
Short IDs (e.g. 6–8 characters) have significantly higher collision probability. A 6-character NanoID from the default 64-char alphabet has only ~68 billion possible values — suitable for a few thousand IDs before collision risk becomes non-trivial. Use the collision probability table above to choose an appropriate size for your expected ID volume.
Can I use NanoID in a browser without npm?
Yes. NanoID supports ESM imports from CDN (e.g. jsDelivr or esm.sh). Import it as a module in a script tag with type="module". This is useful for quick prototyping but not recommended for production — pin to a specific version and consider self-hosting the script.
Does NanoID work in all environments?
NanoID works in all modern browsers, Node.js, Deno, Bun, Cloudflare Workers, and Vercel Edge Functions. For React Native, a polyfill for getRandomValues is required (react-native-get-random-values). The library is designed to be environment-agnostic and detects the available crypto API automatically.