NanoID generator

By Cobra · Last updated

How NanoID entropy works

Each character is drawn uniformly from your alphabet using crypto.getRandomValues. Approximate bits of entropy are size times log2(alphabet length). The default alphabet has 64 URL-safe characters and size 21, which is about 126 bits.

Collision odds rise when size shrinks or the alphabet loses characters (for example hex-only). At about 32 bits you are in toy-token territory. At 64+ bits accidental collisions become unlikely for typical app volumes. At about 126 bits you match common NanoID practice.

Worked example: size 21 vs an 8-character hex ID

Size 21 with the default alphabet yields IDs shaped like V1StGXR8_Z5jdHi6B-myT (illustrative shape). Size 8 with a 16-character hex alphabet is only about 32 bits: fine for demo labels, not for unguessable secrets.

If you need many IDs, raise Count and download the .txt list. Each line is independent; this page does not dedupe against a database.

Limits

NanoIDs are opaque. They are not time-sortable unless you encode time yourself. Prefer UUID v7 or ULID when sort-by-time matters in filenames or indexes.

This page cannot prove global uniqueness; risk is probabilistic from the entropy math. Do not treat NanoID as a password hasher or as a substitute for server-side session secrets without reviewing threat models.

Worked example: picking a size for short share links

Say you want share codes for a link shortener. With the 64-character default alphabet, each character carries 6 bits, so size 10 gives 60 bits and size 21 gives 126 bits. Switch to the No lookalikes preset so people can read codes aloud: the alphabet shrinks, bits per character drop, and you need a slightly longer size to keep the same entropy. Watch the readout under the presets as you change size; it recomputes as size times log2(alphabet length).

Pitfalls

NanoID in JavaScript, Python and Go

Default 21-character IDs, a shorter size, and a custom alphabet in each language.

JavaScript: nanoid

import { nanoid, customAlphabet } from "nanoid"; // npm i nanoid

console.log(nanoid());    // 21 chars, A-Za-z0-9_-
console.log(nanoid(10));  // shorter means more collision risk

// Custom alphabet, for example lowercase hex
const hexId = customAlphabet("0123456789abcdef", 16);
console.log(hexId());

Python: nanoid

from nanoid import generate  # pip install nanoid

print(generate())                          # 21 chars, A-Za-z0-9_-
print(generate(size=10))                   # shorter means more collision risk
print(generate("0123456789abcdef", 16))    # custom alphabet, length 16

Go: github.com/matoous/go-nanoid/v2

package main

import (
	"fmt"

	gonanoid "github.com/matoous/go-nanoid/v2" // go get github.com/matoous/go-nanoid/v2
)

func main() {
	id, err := gonanoid.New() // 21 chars, A-Za-z0-9_-
	if err != nil {
		panic(err)
	}
	fmt.Println(id)

	hex, err := gonanoid.Generate("0123456789abcdef", 16)
	if err != nil {
		panic(err)
	}
	fmt.Println(hex)
}

Each snippet was run on October 14, 2026 with nanoid 6.0.2, nanoid 2.0.0 on PyPI and go-nanoid v2.1.0.

NanoID references and sources

FAQ

What is a NanoID generator?

It mints URL-safe NanoIDs in the browser. The default alphabet is A-Z, a-z, 0-9, underscore, and hyphen (64 characters). Size defaults to 21, which is the NanoID standard.

Does this upload my IDs?

No. Generation runs in your browser only. Copy the list or download a text file. Nothing is uploaded.

NanoID vs UUID vs ULID?

Use NanoID for short opaque URL tokens. Prefer UUID v7 or ULID when you need time ordering. Prefer UUID v4 when you want the classic 122-bit random UUID string shape.

Is size 21 always enough?

For typical app-scale IDs, yes. If the alphabet shrinks or IDs are attacker-guessable entry points, increase size. Check the entropy readout after you change size or alphabet.

Can I use a NanoID as a database primary key?

Yes, many apps do, but random IDs insert in random order, which can fragment some B-tree indexes on large tables. If insert order matters, a time-ordered ID such as UUID v7 or ULID is usually a better fit.

Why are underscores and hyphens in the default alphabet?

They keep the alphabet at 64 characters while staying URL-safe, so IDs need no percent-encoding in paths or query strings. If a hyphen at the start breaks a command line tool, use the A-Za-z or alphanumeric presets.