Skip to main content

Searching...

Tools
Articles
View All Results

Developer Lab · JavaScript

Generate UUID in JavaScript

To generate a UUID in JavaScript, call crypto.randomUUID(). It is built into modern browsers and Node.js, requires no dependencies, and returns an RFC 4122 version 4 UUID backed by a cryptographically secure random number generator. For time-ordered v7 or deterministic v5 IDs, use the uuid npm package.

Quick Answer

Production ready
javascript
// One line - no imports required
const id = crypto.randomUUID();
console.log(id);
// → "550e8400-e29b-41d4-a716-446655440000"

Step-by-Step Guide

Follow these four steps to generate, extend, and safely store UUIDs in any JavaScript runtime.

  1. 1

    Verify your environment

    In browsers, crypto.randomUUID() requires a secure context (HTTPS or localhost). In Node.js, use version 19+ for the global API, or import { randomUUID } from 'node:crypto' on 14.17+.

    javascript
    function canGenerateUUID() {
      return typeof crypto !== 'undefined'
        && typeof crypto.randomUUID === 'function';
    }
  2. 2

    Generate a UUID v4

    Call crypto.randomUUID() anywhere you have access to the Web Crypto API. Each call is independent and thread-safe.

    javascript
    const sessionId = crypto.randomUUID();
    const batch = Array.from({ length: 10 }, () => crypto.randomUUID());
  3. 3

    Install uuid for v7 or v5

    Native APIs only produce v4. Install uuid when you need sortable v7 or deterministic v5 identifiers.

    bash
    npm install uuid
  4. 4

    Validate and store

    Validate external UUIDs at API boundaries. Store as lowercase strings in JavaScript; use binary UUID columns in your database when possible.

    javascript
    const id = crypto.randomUUID().toLowerCase();
    if (!isUUID(incomingId)) throw new Error('Invalid UUID');

Quick Reference

Choose the right UUID version and method for your use case.

Version Method Sortable RFC Dependency Best for
v4 crypto.randomUUID() No 4122 None Session tokens, client IDs, general randomness
v7 uuidv7() Yes 9562 uuid package Database PKs, event logs, chronological sorting
v5 uuidv5(name, namespace) No 4122 uuid package Deterministic IDs from namespace + name
v1 / v3 / v6 uuid package v1/v6 yes 4122 / 9562 uuid package Legacy systems, MAC-based or MD5 namespaces

Environment Compatibility

crypto.randomUUID() availability across JavaScript runtimes.

Runtime v4 support Notes
Chrome / Edge92+Secure context required in production
Firefox95+Same secure-context rule
Safari15.4+iOS 15.4+
Node.js14.17+ (import), 19+ (global)See Node.js guide
Deno1.x+Global crypto.randomUUID()
Bun1.x+Web Crypto compatible
Web WorkersYescrypto global available in dedicated workers
Service WorkersYesSecure context only
Secure context requirements for crypto.randomUUID() HTTPS Works HTTP (non-local) TypeError
crypto.randomUUID() requires a secure context in browsers. localhost counts as secure.

All UUID Versions

UUID v4 - Random (native)

javascript
// 122 bits of CSPRNG randomness, RFC 4122 compliant
const id = crypto.randomUUID();
// → "550e8400-e29b-41d4-a716-446655440000"

UUID v7 - Time-ordered (uuid package)

javascript
import { v7 as uuidv7 } from 'uuid';

const id = uuidv7();
// → "018e8f6a-1b2c-7d3e-9f4a-5b6c7d8e9f0a"
// Later IDs sort after earlier ones (RFC 9562)

UUID v5 - Deterministic namespace

javascript
import { v5 as uuidv5 } from 'uuid';

const id = uuidv5('example.com', uuidv5.DNS);
// → always "cfbff0d1-9375-5685-968c-48ce8b15ae17"

UUID v1 / v3 / v6 - uuid package

javascript
import { v1 as uuidv1, v3 as uuidv3, v6 as uuidv6 } from 'uuid';

uuidv1(); // timestamp + MAC-based node
uuidv3('hello', uuidv3.URL); // MD5 namespace hash
uuidv6(); // reordered v1 for better DB locality (RFC 9562)

Validate and Parse UUIDs

TypeScript types do not validate runtime input. Always check UUIDs from HTTP requests, query params, and user input.

javascript
const UUID_RE =
  /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;

function isUUID(value) {
  return typeof value === 'string' && UUID_RE.test(value);
}

function normalizeUUID(value) {
  if (!isUUID(value)) throw new TypeError('Invalid UUID');
  return value.toLowerCase();
}

// v5 inputs: use stable lowercase names; URLs should be canonical
const name = 'example.com';
const id = uuidv5(name, uuidv5.DNS);

Real-World Use Cases

Optimistic UI (client-side temp IDs)

javascript
function addTodoOptimistically(text, setTodos) {
  const tempId = crypto.randomUUID();
  setTodos((prev) => [...prev, { id: tempId, text, status: 'pending' }]);
  fetch('/api/todos', {
    method: 'POST',
    body: JSON.stringify({ id: tempId, text }),
  });
}

Idempotency keys for API requests

javascript
async function chargeCard(amount, cardToken) {
  const key = crypto.randomUUID();
  sessionStorage.setItem('payment_idempotency_key', key);
  return fetch('/api/payments', {
    method: 'POST',
    headers: { 'Idempotency-Key': key },
    body: JSON.stringify({ amount, cardToken }),
  });
}

Persistent anonymous device ID

javascript
function getDeviceId() {
  const key = 'device_id';
  let id = localStorage.getItem(key);
  if (!id) {
    id = crypto.randomUUID();
    localStorage.setItem(key, id);
  }
  return id;
}

WebSocket correlation IDs

javascript
const ws = new WebSocket('wss://api.example.com/ws');
const connectionId = crypto.randomUUID();
ws.addEventListener('open', () => {
  ws.send(JSON.stringify({ type: 'hello', connectionId }));
});

IndexedDB record keys

javascript
async function saveDraft(db, content) {
  const id = crypto.randomUUID();
  const tx = db.transaction('drafts', 'readwrite');
  tx.objectStore('drafts').put({ id, content, updatedAt: Date.now() });
  await tx.done;
  return id;
}

Distributed tracing correlation IDs

javascript
const correlationId = crypto.randomUUID();
console.info(JSON.stringify({
  level: 'info',
  correlationId,
  message: 'Order created',
  orderId: crypto.randomUUID(),
}));

UUID v4 vs v7 Decision Guide

Use v4 by default. Switch to v7 when insert order and index locality matter at database scale.

UUID version selection flowchart Need an ID? Sortable PK? Deterministic? uuid v7() RFC 9562 v4 default uuid v5() namespace hash
Default to crypto.randomUUID() (v4). Reach for v7 or v5 when sortability or determinism is required.

How UUID v4 Works

crypto.randomUUID() fills 122 bits from the OS CSPRNG. Six bits are fixed: four encode version 4 (0100) and two encode the RFC 4122 variant (10).

UUID v4 128-bit layout random 4xxx yxxx random
128-bit layout: version nibble (4) and variant bits (8/9/a/b) are fixed; all other bits are random.
f47ac10b-58cc-4372-a567-0e02b2c3d479
f47ac10b
32 random bits
58cc
16 random bits
4372
version 4 + 12 random bits
a567
variant 10 + 14 random bits
0e02b2c3d479
48 random bits

With 2^122 possible values, collision risk is negligible for any practical application. The birthday bound for a 50% collision chance requires generating roughly 2.6 billion billion UUIDs.

Common Mistakes

Using Math.random() for IDs

Math.random() is not cryptographically secure and provides only ~53 bits of entropy. Always use crypto.randomUUID().

Calling crypto.randomUUID() over plain HTTP

Non-secure contexts throw TypeError. Use HTTPS in production or localhost during development.

Building UUIDs with string concatenation

Manual templates often violate version/variant bit rules. Use the platform API or the uuid package.

Skipping browser support checks for legacy targets

Pre-2021 browsers lack native support. Feature-detect and fall back to the uuid package when needed.

Using v4 as a database PK at very large scale

Random v4 inserts fragment B-tree indexes. Above ~10M rows, consider UUID v7 for chronological insert locality.

Coercing UUIDs to numbers

UUIDs exceed JavaScript's safe integer range. Keep them as strings end to end.

Best Practices, Performance, and Security

Best practices

Use crypto.randomUUID() for all new v4 code.

Store UUIDs as lowercase strings for consistent comparison.

Use UUID v7 for time-ordered database primary keys (RFC 9562).

Performance

Native crypto.randomUUID() typically generates millions of IDs per second in V8 (exact throughput varies by OS CSPRNG and hardware). Each call is independent with no shared mutable state.

Bulk generation: Array.from({ length: n }, () => crypto.randomUUID()) is idiomatic and efficient.

Security

Entropy source: OS CSPRNG via Web Crypto. On Windows this maps to BCryptGenRandom; on Linux and macOS to /dev/urandom.

CSPRNG suitable for: session tokens, CSRF tokens, idempotency keys, and client-side correlation IDs.

Caveat: Secure context required in browsers. Never use Math.random() for security-sensitive identifiers.

Installation

UUID v4 (native)

bash
# No installation needed

Available globally in Node 19+, browsers since 2021, Deno, and Bun.

uuid package (v7, v5, v1, v3, v6)

bash
npm install uuid
# or: pnpm add uuid / yarn add uuid / bun add uuid
javascript
// ESM
import { v7 as uuidv7 } from 'uuid';
// CommonJS
const { v4: uuidv4 } = require('uuid');

Frequently Asked Questions

How do I generate a UUID in JavaScript?

Call crypto.randomUUID() with no imports. It returns an RFC 4122 version 4 UUID string like "550e8400-e29b-41d4-a716-446655440000". For time-ordered v7 or deterministic v5 UUIDs, install the uuid package and use uuidv7() or uuidv5().

Is crypto.randomUUID() cryptographically secure?

Yes. crypto.randomUUID() draws from the same CSPRNG as crypto.getRandomValues(), suitable for session tokens, CSRF tokens, and idempotency keys. Do not use Math.random() for identifiers.

Does crypto.randomUUID() work in Node.js?

Yes. Node.js 19+ exposes crypto.randomUUID() on the global crypto object. On Node.js 14.17 through 18, import it: import { randomUUID } from "node:crypto".

What is the difference between UUID v4 and v7 in JavaScript?

UUID v4 (crypto.randomUUID()) is fully random and not sortable. UUID v7 (via the uuid package) embeds a millisecond timestamp in the leading bits, so IDs sort chronologically. Use v7 for database primary keys at scale; use v4 for general-purpose random IDs.

When should I use the uuid npm package?

Use the uuid package when you need UUID v7 (time-ordered), v5 or v3 (deterministic from a namespace), v1 (timestamp + MAC), or v6. Native crypto.randomUUID() only generates v4.

Why does crypto.randomUUID() throw a TypeError on HTTP?

The Web Crypto API is restricted to secure contexts: HTTPS and localhost. On plain HTTP (non-localhost), crypto.randomUUID() throws TypeError. Serve production apps over HTTPS.

How do I validate a UUID string in JavaScript?

Use a regex test: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value). Normalize to lowercase before comparing or storing.

Does crypto.randomUUID() work in Web Workers?

Yes. Web Workers have access to the crypto global and crypto.randomUUID() works the same as on the main thread, including the secure-context requirement.

Should I store UUIDs as strings or binary in JavaScript apps?

In JavaScript, UUIDs are strings. When persisting to a database, prefer native binary UUID types (PostgreSQL UUID, MySQL BINARY(16)) over VARCHAR(36) for smaller indexes and faster comparisons.

What RFC standards apply to JavaScript UUID generation?

crypto.randomUUID() produces RFC 4122 version 4 UUIDs. UUID v7 follows RFC 9562 (May 2024). The uuid npm package implements RFC 4122 and RFC 9562 versions.

Key definitions

UUID
128-bit universally unique identifier, usually shown as 36 hex characters with hyphens.
CSPRNG
Cryptographically secure pseudo-random number generator. The entropy source behind crypto.randomUUID().
Secure context
Browser environments where Web Crypto is available: HTTPS origins and localhost.
RFC 4122
IETF standard defining UUID versions 1 through 5. Version 4 is random.