About NanoID Generator
NanoID is a compact random identifier: 21 characters by default, drawn from a 64-character alphabet of A-Z, a-z, 0-9, plus - and _. That gives about 126 bits of entropy - marginally more than a UUID v4's 122 - in 21 characters rather than 36.
The size difference is the whole appeal. Every character in the alphabet is URL-safe without escaping, so a NanoID can go straight into a path segment, a query parameter or a filename. For anything that appears in a link a user might see or type, 21 characters is a meaningful improvement over 36, and it is why NanoID is common for short links, share tokens and public-facing record ids.
The collision arithmetic is comfortable at the default length: generating a thousand IDs per second, you would need roughly 40 thousand years for a 1% chance of a single collision. Shortening the ID cuts that sharply, though - the relationship is exponential, so a 10-character NanoID has about 60 bits and collides far sooner than intuition suggests. If you shorten it, do the birthday-problem arithmetic for your actual volume and add a uniqueness constraint in the database.
Two properties NanoID does not have, which are the reasons not to choose it: there is no timestamp, so it does not sort chronologically and is no better than UUID v4 as a clustered primary key on a large table; and it is not a UUID, so it will not fit a uuid column or validate against a UUID parser.
Generation uses the browser's cryptographically secure random source, and nothing is transmitted.
How to use the NanoID Generator
- Press generate for a 21-character ID from the default URL-safe alphabet.
- Copy it - no escaping is needed for URLs, filenames or HTML attributes.
- If you shorten the length, work out the collision probability for your volume first, and enforce uniqueness in the database.
- For a database primary key on a large table, prefer a time-ordered identifier (UUID v7 or ULID) instead.
Examples
-
Length
21 -
Custom alphabet
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_
NanoID Generator in code
The same operation this tool performs, in the languages you are most likely to need it.
import { nanoid, customAlphabet } from "nanoid";
nanoid(); // "V1StGXR8_Z5jdHi6B-myT" (21 chars, ~126 bits)
nanoid(10); // shorter - and far more collision-prone
// A custom alphabet, e.g. digits only for a numeric code
const numeric = customAlphabet("0123456789", 6);
numeric(); // "834721" - only ~20 bits, needs a uniqueness check
// Unambiguous alphabet for codes a human will read aloud or type
// (no 0/O, 1/l/I)
const readable = customAlphabet("23456789ABCDEFGHJKLMNPQRSTUVWXYZ", 8);
from nanoid import generate
generate() # 21 chars, default alphabet
generate(size=12)
generate("0123456789abcdef", 16) # custom alphabet
# Without the dependency - secrets gives the same guarantees
import secrets
secrets.token_urlsafe(16) # ~22 chars, 128 bits, URL-safe
-- Fixed-length text, and let the database enforce uniqueness
CREATE TABLE links (
id CHAR(21) PRIMARY KEY,
target TEXT NOT NULL,
created timestamptz NOT NULL DEFAULT now()
);
-- NanoID has no timestamp, so it gives no index locality - the same
-- scattered-insert problem as random UUID v4. On a large table,
-- consider a time-ordered internal key plus the NanoID as the
-- public-facing identifier:
CREATE TABLE links (
pk uuid PRIMARY KEY DEFAULT uuidv7(), -- clustered, sequential
slug CHAR(21) NOT NULL UNIQUE, -- what appears in URLs
target TEXT NOT NULL
);
When you need this
- Short-link slugs and share tokens that appear in URLs people see.
- Public-facing record identifiers where a 36-character UUID looks unwieldy.
- Filenames and object keys in blob storage.
- Invite or referral codes, usually with a custom unambiguous alphabet.
- Client-generated identifiers in an offline-capable app, where compactness matters.
Common problems and what causes them
- Shortening the ID without checking the arithmetic
- Entropy falls exponentially with length. 21 characters is about 126 bits; 10 characters is about 60, which collides after a few billion values - reachable for a busy service. Compute the birthday bound for your real volume and always add a unique constraint.
- Using NanoID as a clustered primary key on a large table
- It is fully random, so it has exactly the same index-scattering problem as UUID v4: page splits and degrading insert throughput as the table grows. Use a time-ordered key internally and expose the NanoID as a secondary unique column.
- Expecting it to be a UUID
- NanoID is not a UUID and has no version or variant bits. It will not fit a uuid-typed column, will not validate against a UUID parser, and cannot be converted to one without changing the value.
- A custom alphabet with ambiguous characters
- If a human will read the code aloud or type it from a screen, 0/O and 1/l/I cause real errors. Use an alphabet that excludes them - Crockford Base32 already does.
- Treating a NanoID as a secret
- It is unguessable at the default length, which is not the same as secret. It will appear in logs, referrer headers and browser history like any URL component, so it is fine as an identifier and wrong as a long-lived credential.
- A custom alphabet that is not URL-safe
- The default alphabet is chosen so no character needs escaping. Adding + or / means the ID must be percent-encoded in URLs, which reintroduces exactly the problem NanoID was chosen to avoid.
FAQ
- NanoID or UUID - which should I use?
- NanoID when the identifier appears in a URL and its length matters: 21 characters against 36, with slightly more entropy. UUID when you want a standard format that every database, language and tool already understands. For a primary key on a large table, prefer time-ordered UUID v7 over either.
- How likely are NanoID collisions?
- At the default 21 characters, negligible - roughly 40 thousand years at a thousand IDs per second for a 1% chance of one collision. That guarantee is entirely length-dependent, though, and disappears quickly as you shorten it.
- Is NanoID secure?
- It uses a cryptographically secure random source, so the values are unpredictable. That makes it a sound unguessable identifier. It is still not a credential: like any URL component it ends up in logs and history.
- Can I make NanoIDs shorter?
- Yes, and it is the main thing to be careful about. Entropy is length times log2(alphabet size), so cutting length cuts collision resistance exponentially. Do the arithmetic for your expected volume, and let the database enforce uniqueness as a backstop.
- Is a NanoID URL-safe?
- With the default alphabet, yes - A-Za-z0-9 plus - and _, none of which need percent-encoding. Change the alphabet and you have to check that property yourself.
Related reading
- NanoID vs UUID
- UUID vs ULID vs NanoID
- UUID generator the standard format
- ULID generator time-sortable