How to Generate and Use UUIDs in JavaScript

Published on February 1, 2026 · 7 min read

A practical guide to UUID generation in JavaScript — from the built-in crypto.randomUUID() API to the uuid npm package, covering all major versions, validation, and real-world database considerations.

UUIDs (Universally Unique Identifiers) are 128-bit values used to identify resources without central coordination. Whether you're building a REST API, syncing data across microservices, or generating primary keys for a distributed database, JavaScript offers several robust ways to create and work with UUIDs. This guide covers every approach you'll need in production.

The Modern Way: crypto.randomUUID()

Since Node.js 19+ and all modern browsers (Chrome 92+, Firefox 95+, Safari 15.4+), you can generate a Version 4 UUID with zero dependencies:

const id = crypto.randomUUID(); console.log(id); // → "3b241101-e2bb-4d7a-8702-9e1a4c3e7f92"

This is the recommended approach for most use cases. The method is cryptographically secure, fast, and available in both the browser and Node.js without installing anything. It returns a lowercase, hyphenated string conforming to RFC 9562.

💡 Best Practice: If you only need random UUIDs (v4), crypto.randomUUID() is all you need. Skip the npm package entirely.

The uuid npm Package

When you need more than random UUIDs — deterministic name-based IDs, time-ordered sorting, or validation utilities — the uuid package (60M+ weekly downloads) is the go-to library:

npm install uuid

Then use it in your code:

import { v1, v4, v5, v7, validate, version } from 'uuid'; // Version 4 — random (same as crypto.randomUUID) const random = v4(); // Version 1 — timestamp + MAC-based const timeBased = v1(); // Version 5 — deterministic (SHA-1 of namespace + name) const DNS_NAMESPACE = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; const deterministic = v5('api.example.com', DNS_NAMESPACE); // Always → "cfbff0d1-9375-5685-968c-48ce8b15ae17" // Version 7 — Unix timestamp-ordered random const ordered = v7(); // Validate & inspect console.log(validate(random)); // true console.log(version(random)); // 4

UUID Versions Explained

Not all UUIDs are created equal. Each version has a different generation strategy and set of trade-offs. Here's what matters in practice:

Version Source Sortable Deterministic Best For
v1 Timestamp + MAC Partially No Legacy systems, audit logs
v4 Random No No General-purpose IDs (most common)
v5 SHA-1 (namespace + name) No Yes Consistent mapping (URLs, DNS)
v7 Unix ms timestamp + random Yes No Database PKs, time-ordered data
⚠️ Privacy Note: Version 1 UUIDs can expose your machine's MAC address. Avoid v1 in client-facing code. Prefer v4 or v7 instead.

Why UUID v7 Is Gaining Traction

UUID v7 (added in RFC 9562, 2024) embeds a Unix millisecond timestamp in the most significant bits, making IDs naturally sort in chronological order while remaining globally unique. This solves the biggest complaint about v4 in databases: random key distribution causing index fragmentation and poor write performance.

import { v7 } from 'uuid'; // Generate three v7 UUIDs in sequence const a = v7(); // "018e7d2e-1c3a-7b9f-..." const b = v7(); // "018e7d2e-1c3b-7a2d-..." const c = v7(); // "018e7d2e-1c3c-7d91-..." // They sort correctly as strings! console.log([c, a, b].sort()); // → [a, b, c] (chronological order)

Validation and Parsing

Accepting UUIDs from user input or external APIs? Always validate. Here are two approaches:

With the uuid Package

import { validate, version } from 'uuid'; validate('not-a-uuid'); // false validate('f47ac10b-58cc-4372-a567-0e02b2c3d479'); // true version('f47ac10b-58cc-4372-a567-0e02b2c3d479'); // 4

With a Regex (No Dependencies)

const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-7][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; function isUUID(str) { return UUID_RE.test(str); } isUUID('f47ac10b-58cc-4372-a567-0e02b2c3d479'); // true isUUID('hello-world'); // false

Need to test your own UUID regex patterns? Our Regex Tester lets you validate patterns against sample UUIDs in real time.

UUIDs vs Auto-Increment IDs

Choosing between UUIDs and auto-incrementing integers is one of the most common architecture decisions. Here's when each makes sense:

Use UUIDs when:
  • You have multiple databases or services generating IDs independently
  • IDs are exposed in URLs and you want to prevent enumeration attacks
  • You need to generate IDs client-side before writing to the database
  • Merging data from different sources without conflicts is required
Use auto-increment when:
  • You have a single database with straightforward sequential writes
  • Storage efficiency matters (4 bytes vs 16 bytes per row)
  • You need maximum query performance on primary keys
  • Human-readable IDs are helpful (order #12345 vs order #a7f2d...)

Database Considerations

How you store UUIDs in your database significantly impacts performance. Random v4 UUIDs cause B-tree index fragmentation because inserts scatter across the tree. Here's how to handle it:

Database Recommended Type Notes
PostgreSQL uuid Native 16-byte type, use gen_random_uuid()
MySQL BINARY(16) Avoid CHAR(36) — wastes 20 bytes per row
SQLite BLOB or TEXT No native UUID; store as 16-byte blob for perf
MongoDB UUID (BSON Binary subtype 4) Use the UUID() constructor in drivers
💡 Pro Tip: If you use UUIDs as primary keys, strongly consider UUID v7. Its time-ordered nature keeps B-tree indexes sequential, giving you the best of both worlds: global uniqueness and insert performance close to auto-increment.

PostgreSQL Example

CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), email TEXT NOT NULL UNIQUE, created_at TIMESTAMPTZ DEFAULT now() ); -- Insert without specifying ID INSERT INTO users (email) VALUES ('[email protected]'); -- Or pass a UUID from JavaScript INSERT INTO users (id, email) VALUES ('018e7d2e-1c3a-7b9f-8a2d-4b5c6d7e8f90', '[email protected]');

Practical Patterns

Generate IDs in an Express API

import express from 'express'; const app = express(); app.post('/api/orders', (req, res) => { const order = { id: crypto.randomUUID(), ...req.body, createdAt: new Date().toISOString() }; // save to DB... res.status(201).json(order); });

Convert UUID to Bytes and Back

import { parse, stringify } from 'uuid'; // UUID string → Uint8Array (16 bytes) const bytes = parse('f47ac10b-58cc-4372-a567-0e02b2c3d479'); // Uint8Array → UUID string const str = stringify(bytes); // → "f47ac10b-58cc-4372-a567-0e02b2c3d479"

Working with binary representations is useful when you need to store UUIDs efficiently or convert between formats. You can also Base64-encode the bytes for compact URL-safe transport.

Quick Reference: Generating UUIDs

// Browser + Node.js 19+ (no dependencies) crypto.randomUUID(); // uuid package — all versions import { v1, v4, v5, v7 } from 'uuid'; v4(); // random v7(); // time-ordered random v5('name', '6ba7b810-...'); // deterministic v1(); // timestamp + MAC // Validation import { validate } from 'uuid'; validate('f47ac10b-58cc-4372-...'); // true

Useful Tools

Try these free developer tools to work with UUIDs and related formats:

UUID Generator JSON Formatter Base64 Encoder Regex Tester