nanoid, shortid, uniqid, and uuid are libraries used to generate unique identifiers for keys, tokens, and entity IDs in JavaScript applications. nanoid is a modern, secure, and tiny library that has become the industry standard for most use cases. uuid generates RFC4122 compliant IDs, ensuring compatibility with systems that require standard UUID formats. shortid was popular for creating short, unique IDs but is now deprecated and should be avoided. uniqid generates unique IDs based on time and random numbers but lacks the security guarantees and maintenance of modern alternatives.
In modern web development, generating unique identifiers is a daily task. Whether you are creating temporary keys for React lists, session tokens for authentication, or primary keys for database records, the library you choose impacts security, performance, and compatibility. Let's compare nanoid, shortid, uniqid, and uuid to understand which tool fits your architecture.
Before looking at features, we must address the maintenance status. Using a deprecated library introduces security risks and technical debt.
nanoid is actively maintained and widely adopted. It is the current community standard.
// nanoid: Active and recommended
import { nanoid } from 'nanoid';
const id = nanoid();
uuid is also actively maintained. It is the standard for RFC4122 UUIDs.
// uuid: Active and standard
import { v4 as uuidv4 } from 'uuid';
const id = uuidv4();
shortid is deprecated. The repository is archived, and the maintainer advises switching to nanoid.
// shortid: DEPRECATED - Do not use in new projects
import shortid from 'shortid';
const id = shortid.generate();
uniqid has low activity and is considered legacy. It does not have the same security guarantees as modern tools.
// uniqid: Legacy/Low maintenance
import uniqid from 'uniqid';
const id = uniqid();
For tokens or IDs that should not be guessed, cryptographic strength matters. Predictable IDs can lead to security vulnerabilities like enumeration attacks.
nanoid uses cryptographically strong random values. It is safe for session IDs and security tokens.
// nanoid: Secure random bytes
import { nanoid } from 'nanoid';
// Uses crypto.getRandomValues() in browser or crypto.randomBytes in Node
const secureId = nanoid();
uuid (specifically v4) also uses cryptographically strong random numbers. It is safe for security contexts.
// uuid v4: Secure random bytes
import { v4 as uuidv4 } from 'uuid';
const secureId = uuidv4();
shortid used a secure random generator, but due to lack of maintenance, potential unpatched vulnerabilities exist. It is no longer trusted.
// shortid: Was secure, now unsafe due to deprecation
import shortid from 'shortid';
const id = shortid.generate(); // Not recommended
uniqid relies heavily on the current time and process ID. It is not cryptographically secure. Do not use it for authentication tokens.
// uniqid: Time-based, predictable
import uniqid from 'uniqid';
const id = uniqid(); // Easy to guess if time is known
The shape of the ID affects database storage, URL readability, and user experience.
nanoid generates URL-friendly strings by default. They are shorter than UUIDs, saving space in databases and URLs.
// nanoid: Short, URL-friendly (default 21 chars)
import { nanoid } from 'nanoid';
console.log(nanoid()); // e.g., "V1StGXR8_Z5jdHi6B-myT"
uuid generates standard 36-character strings with hyphens. This is verbose but universally recognized.
// uuid: Standard format (36 chars)
import { v4 as uuidv4 } from 'uuid';
console.log(uuidv4()); // e.g., "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"
shortid generated short, non-sequential strings similar to nanoid, but with less control over the alphabet.
// shortid: Short string (deprecated)
import shortid from 'shortid';
console.log(shortid.generate()); // e.g., "P8xG9z"
uniqid generates hex strings based on time. They can be prefixed but are generally longer than nanoid and less readable.
// uniqid: Hex string based on time
import uniqid from 'uniqid';
console.log(uniqid()); // e.g., "65a1f2c8b9e10"
Sometimes you need specific character sets or asynchronous generation to avoid blocking the main thread.
nanoid offers excellent customization. You can define your own alphabet or use the async version for better performance in Node.js.
// nanoid: Custom alphabet and async support
import { customAlphabet } from 'nanoid';
const nanoidHex = customAlphabet('0123456789ABCDEF', 10);
console.log(nanoidHex()); // e.g., "4F9A2B1C3D"
import { nanoidAsync } from 'nanoid/async';
const id = await nanoidAsync(); // Non-blocking
uuid allows different versions (v1 for time-based, v3/v5 for namespace-based), but you cannot easily change the character set.
// uuid: Version selection
import { v1, v5 } from 'uuid';
const timeBased = v1();
const namespaceBased = v5('my-name', v5.URL);
shortid allowed some seed customization but is now irrelevant due to deprecation.
// shortid: Limited customization (legacy)
import shortid from 'shortid';
shortid.seed(123); // No longer supported/maintained
uniqid allows adding a prefix, which is useful for debugging, but lacks deep configuration.
// uniqid: Prefix support
import uniqid from 'uniqid';
console.log(uniqid.prefix('user_')); // e.g., "user_65a1f2c8b9e10"
All four packages work in Node.js and browsers, but bundle size and native API usage differ.
nanoid is extremely small and has no dependencies. It automatically detects the environment to use the best crypto API.
// nanoid: Zero dependencies, tiny bundle
import { nanoid } from 'nanoid';
// Works in React, Vue, Node, Deno, Bun without config
uuid is larger and has dependencies. In modern environments, you might prefer the native crypto.randomUUID() instead.
// uuid: Heavier bundle
import { v4 } from 'uuid';
// OR use native API in modern Node/Browsers:
// const id = crypto.randomUUID();
shortid and uniqid work in both environments but do not offer advantages over nanoid in terms of compatibility or size.
// shortid/uniqid: Universal but outdated
import shortid from 'shortid';
import uniqid from 'uniqid';
// No specific environment benefits over nanoid
| Feature | nanoid | uuid | shortid | uniqid |
|---|---|---|---|---|
| Status | ✅ Active | ✅ Active | ❌ Deprecated | ⚠️ Legacy |
| Security | 🔒 High | 🔒 High | ⚠️ Unknown | 🔓 Low |
| Length | Short (21) | Long (36) | Short | Medium |
| Format | URL-friendly | RFC4122 | URL-friendly | Hex |
| Bundle | Tiny | Medium | Small | Small |
| Customizable | Yes | Limited | No | Prefix only |
For the vast majority of frontend and full-stack applications, nanoid is the best choice. It is secure, tiny, and actively maintained. It solves the same problems as shortid without the technical debt.
Use uuid only if you have a strict requirement for RFC4122 compliance — for example, if your database schema or third-party API specifically demands standard UUID formatting. In modern Node.js or browser environments, consider using the native crypto.randomUUID() instead of the uuid package to save bundle space.
Avoid shortid completely in new code. It is deprecated and unmaintained. Avoid uniqid for anything security-related, as its time-based generation is predictable.
Stick to nanoid for simplicity and security, or uuid for standardization. There is rarely a need to reach for the older libraries today.
Do NOT choose shortid for new projects. It is officially deprecated and no longer maintained. The creator explicitly recommends migrating to nanoid. Only use this if you are maintaining legacy code that cannot be refactored immediately.
Choose nanoid for almost all new projects. It is secure, tiny, and fast. It is the recommended replacement for shortid and works well for URL-friendly IDs, session tokens, and primary keys where standard UUID format is not required.
Avoid uniqid for security-sensitive tasks. It relies on time-based generation which can be predictable. It might work for temporary client-side keys where collisions are not critical, but nanoid is a safer and equally easy drop-in replacement.
Choose uuid when you need strict RFC4122 compliance. If your backend database, external API, or infrastructure tools require standard UUID strings (like 550e8400-e29b...), this package ensures interoperability. It is larger than nanoid but necessary for standardization.
Amazingly short non-sequential url-friendly unique id generator.
ShortId creates amazingly short non-sequential url-friendly unique ids. Perfect for url shorteners, MongoDB and Redis ids, and any other id users might see.
A-Z, a-z, 0-9, _-cluster (automatically), custom seeds, custom alphabet.ShortId does not generate cryptographically secure ids, so don't rely on it to make IDs which are impossible to guess.
const shortid = require('shortid');
console.log(shortid.generate());
// PPBqWA9
Mongoose Unique Id
_id: {
'type': String,
'default': shortid.generate
},
The best way to use shortid in the browser is via browserify or webpack.
These tools will automatically only include the files necessary for browser compatibility.
All tests will run in the browser as well:
## build the bundle, then open Mocha in a browser to see the tests run.
$ grunt build open
~/projects/shortid ❯ node examples/examples.js
eWRhpRV
23TplPdS
46Juzcyx
dBvJIh-H
2WEKaVNO
7oet_d9Z
dogPzIz8
nYrnfYEv
a4vhAoFG
hwX6aOr7
shortId was created for Node Knockout 2011 winner for Most Fun Doodle Or Die.
Millions of doodles have been saved with shortId filenames. Every log message gets a shortId to make it easy
for us to look up later.
Here are some other projects that use shortId:
var shortid = require('shortid');
shortid.generate()Returns string non-sequential unique id.
Example
users.insert({
_id: shortid.generate(),
name: '...',
email: '...'
});
shortid.characters(string)Default: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_'
Returns new alphabet as a string
Recommendation: If you don't like _ or -, you can to set new characters to use.
Optional
Change the characters used.
You must provide a string of all 64 unique characters. Order is not important.
The default characters provided were selected because they are url safe.
Example
// use $ and @ instead of - and _
shortid.characters('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$@');
// any 64 unicode characters work, but I wouldn't recommend this.
shortid.characters('ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ①②③④⑤⑥⑦⑧⑨⑩⑪⑫');
shortid.isValid(id)Returns boolean
Check to see if an id is a valid shortid. Note: This only means the id could have been generated by shortid, it doesn't guarantee it.
Example
shortid.isValid('41XTDbE');
// true
shortid.isValid('i have spaces');
// false
shortid.worker(integer)Default: process.env.NODE_UNIQUE_ID || 0
Recommendation: You typically won't want to change this.
Optional
If you are running multiple server processes then you should make sure every one has a unique worker id. Should be an integer between 0 and 16.
If you do not do this there is very little chance of two servers generating the same id, but it is theoretically possible
if both are generated in the exact same second and are generating the same number of ids that second and a half-dozen random numbers are all exactly the same.
Example
shortid.worker(1);
shortid.seed(integer)Default: 1
Recommendation: You typically won't want to change this.
Optional
Choose a unique value that will seed the random number generator so users won't be able to figure out the pattern of the unique ids. Call it just once in your application before using shortId and always use the same value in your application.
Most developers won't need to use this, it's mainly for testing ShortId.
If you are worried about users somehow decrypting the id then use it as a secret value for increased encryption.
Example
shortid.seed(1000);
Hi! Thanks for checking out this project! My name is Dylan Greene. When not overwhelmed with my two young kids I enjoy contributing
to the open source community. I'm also a tech lead at Opower.
Here's some of my other Node projects:
| Name | Description | npm Downloads |
|---|---|---|
npm‑check | Check for outdated, incorrect, and unused dependencies. | |
grunt‑notify | Automatic desktop notifications for Grunt errors and warnings. Supports OS X, Windows, Linux. | |
space‑hogs | Discover surprisingly large directories from the command line. | |
rss | RSS feed generator. Add RSS feeds to any project. Supports enclosures and GeoRSS. | |
grunt‑prompt | Interactive prompt for your Grunt config using console checkboxes, text input with filtering, password fields. | |
xml | Fast and simple xml generator. Supports attributes, CDATA, etc. Includes tests and examples. | |
changelog | Command line tool (and Node module) that generates a changelog in color output, markdown, or json for modules in npmjs.org's registry as well as any public github.com repo. | |
grunt‑attention | Display attention-grabbing messages in the terminal | |
observatory | Beautiful UI for showing tasks running on the command line. | |
anthology | Module information and stats for any @npmjs user | |
grunt‑cat | Echo a file to the terminal. Works with text, figlets, ascii art, and full-color ansi. |
This list was generated using anthology.
Copyright (c) 2016 Dylan Greene, contributors.
Released under the MIT license.
Screenshots are CC BY-SA (Attribution-ShareAlike).