mrkeyoor.com_
Wed 05 Aug 19:55 UTC
npmUtilsupdated 05 Aug 2026

nanoid

Nano ID generates short, URL-safe, cryptographically random string IDs. The default call returns 21 characters from the A-Za-z0-9_- alphabet, packing about the same randomness as a UUID v4 (126 vs 122 bits) into 15 fewer characters. It has zero dependencies, the README documents the core at 118 bytes minified and brotlied, and it reads randomness from the Web Crypto API or Node's crypto module rather than Math.random. A large slice of its downloads is transitive: PostCSS depends on the 3.x line, which the author still maintains alongside v6.

Verdict

The best pick when you specifically want short, random, URL-safe IDs and control over the alphabet; it is tiny, fast, and impeccably maintained. If a plain UUID works, crypto.randomUUID costs nothing, and if IDs become database primary keys at scale, prefer a sortable scheme instead.

API stability4/5The API surface (nanoid, customAlphabet, customRandom) has been unchanged for years; majors mostly ratchet packaging, ESM-only at v4 and Node floors since, which still breaks installs even though code rarely changes.
Docs4/5The README is the documentation and it is thorough: security rationale, benchmarks, collision calculator link, and per-environment guidance including an honest section on why not to use it for React keys.
Maintenance5/5Pushed August 2026, zero open issues and PRs at the time of writing, active releases on both the 6.x and legacy 3.x lines (3.3.16 shipped July 2026), backed by Evil Martians.
Ecosystem5/5About 233M weekly downloads (a chunk transitive via PostCSS), ports to more than 20 languages for matching client/server IDs, and helper packages like nanoid-dictionary for common alphabets.

Use it if

  • You need short IDs for URLs, slugs, or user-facing references where a 36-character UUID is ugly and the 21-character default (or shorter, at your own risk) fits
  • You want to tune the tradeoff: customAlphabet lets you set exactly which characters and how many, with a published collision calculator to check your choice
  • You generate IDs in the browser or edge runtimes and want something tiny that uses Web Crypto correctly, including uniform distribution instead of the biased modulo trick
  • You need deterministic IDs in tests: customRandom accepts a seeded generator so snapshots stay stable
Skip it if

Setup reality

npm install nanoid and one import; there is no config and types are bundled. The friction is environmental: ESM-only means CJS projects need dynamic import or the old 3.x line, Jest setups without proper ESM support choke on it, and v6's engines field will refuse Node 20 in CI images that have not been bumped. React Native needs the react-native-get-random-values polyfill imported before nanoid. Also do not benchmark-shop the non-secure build: since the v6 speedups the secure default is the faster one.

Patterns

Generate a default 21-character IDgenerate-id

import { nanoid } from 'nanoid'

const id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT"

IDs come from a hardware random source and can start with - or _, which matters for systems with reserved prefixes.

Generate a shorter or longer IDcustom-length

import { nanoid } from 'nanoid'

nanoid(10) //=> "IRFa-VaY2b"
nanoid(32) // longer, lower collision odds

Shorter means more collisions: check the nano-id-cc calculator before shipping anything under the default 21 characters.

Restrict the alphabetcustom-alphabet

import { customAlphabet } from 'nanoid'

const hexId = customAlphabet('1234567890abcdef', 12)
hexId() //=> "4f90d13a42bf"

const orderNo = customAlphabet('346789ABCDEFGHJKLMNPQRTUVWXY', 8)

Removing look-alike characters (0/O, 1/l/I) is the common use; the nanoid-dictionary package has prebuilt alphabets. Max 256 symbols.

Deterministic IDs with a seeded generatorseeded-ids-for-tests

import { customRandom, urlAlphabet } from 'nanoid'
import seedrandom from 'seedrandom'

const rng = seedrandom('test-seed')
const testId = customRandom(urlAlphabet, 21, size =>
  new Uint8Array(size).map(() => 256 * rng())
)
testId() // same sequence every run

The project warns that the internal call sequence may change between versions, so seeded output is only stable while you pin the nanoid version.

Use the non-secure build where crypto is missingnon-secure-fallback

import { nanoid } from 'nanoid/non-secure'

const id = nanoid() //=> "Uakgb_J5m9g-0JDMbcJqLJ"

Despite the name this is not a speed hack: the README benchmark shows it far slower than the secure default. Use it only in environments without a hardware random source.

Do not use nanoid() for React keysreact-keys-antipattern

// wrong: new key every render, remounts every item
todos.map(todo => <li key={nanoid()}>{todo.text}</li>)

// right: use a stable id stored on the data
todos.map(todo => <li key={todo.id}>{todo.text}</li>)

Keys must be stable across renders. For linking labels to inputs, React's built-in useId() is the tool, not nanoid.

Use in React Native and Exporeact-native-setup

import 'react-native-get-random-values'
import { nanoid } from 'nanoid'

const id = nanoid()

React Native has no built-in crypto; the polyfill import must come before the nanoid import or you get a runtime error.

Prefix IDs for PouchDB/CouchDBcouchdb-safe-ids

import { nanoid } from 'nanoid'

await db.put({
  _id: 'doc-' + nanoid(),
  title: 'hello'
})

CouchDB reserves IDs starting with an underscore, and nanoid can legitimately generate one; always prefix.

Brand IDs as opaque types in TypeScripttypescript-branded-ids

declare const userIdBrand: unique symbol
type UserId = string & { [userIdBrand]: true }

const id = nanoid<UserId>()

interface User {
  id: UserId
  name: string
}

The generic parameter casts the returned string to your branded type, so a UserId cannot be passed where an OrderId is expected.

Generate IDs from the terminalcli-generate

$ npx nanoid
LZfXLFzPPR4NNrgjlWDxn
$ npx nanoid --size 10
L3til0JS4z
$ npx nanoid --alphabet abc --size 15
bccbcabaabaccab

--alphabet requires --size to be set explicitly; handy for one-off tokens without writing a script.

Alternatives

PackageRegistryPick it when
uuidnpmYou need standard RFC UUIDs (v4, v7) for interoperability with databases and other systems that expect the format.
ulidnpmYou want lexicographically sortable IDs with an embedded timestamp for pagination and index locality.
@paralleldrive/cuid2npmYou want collision-resistant IDs designed to avoid leaking any timing information, at some length cost.