All Tools / Blog / How to Generate a UUID in JavaScript, Python, and the Command Line

How to Generate a UUID in JavaScript, Python, and the Command Line

4 min read

UUIDs (Universally Unique Identifiers) are 128-bit identifiers formatted as 32 hex characters separated by hyphens: 550e8400-e29b-41d4-a716-446655440000. They're used everywhere databases need a primary key that doesn't require a central authority to assign — user IDs, session tokens, file names, API resources.

UUID versions

There are five UUID versions. Version 4 is what most people want.

Version How it's generated Use when
v1 Timestamp + MAC address You need sortable UUIDs tied to a specific machine
v3 MD5 hash of namespace + name You need deterministic UUIDs (same input = same UUID)
v4 Random Default choice — unique, no coordination required
v5 SHA-1 hash of namespace + name Like v3 but SHA-1 instead of MD5
v7 Unix timestamp + random Sortable like v1, without the MAC address privacy leak

Use v4 for most things. Use v7 if you need the UUIDs to sort chronologically (useful for database indexes).

JavaScript — browser

Modern browsers have crypto.randomUUID() built in since 2021. No library needed.

const id = crypto.randomUUID();
console.log(id);
// "550e8400-e29b-41d4-a716-446655440000"

Supported in Chrome 92+, Firefox 95+, Safari 15.4+, Edge 92+. If you need to support older browsers, use the manual approach below or a library.

Manual v4 UUID (no dependencies, works everywhere):

function uuidv4() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        const r = crypto.getRandomValues(new Uint8Array(1))[0] & 0xf;
        const v = c === 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
}

console.log(uuidv4());
// "a3bb189e-8bf9-3888-9912-ace4e6543002"

This uses crypto.getRandomValues() which is cryptographically secure. Never use Math.random() for UUID generation — it's not cryptographically random and collisions become likely at scale.

JavaScript — Node.js

Node.js 14.17+ includes crypto.randomUUID() in the built-in crypto module:

const { randomUUID } = require('crypto');

const id = randomUUID();
console.log(id);

Or with ES modules:

import { randomUUID } from 'crypto';

const id = randomUUID();

For older Node.js versions or if you need v1/v3/v5/v7, use the uuid package:

npm install uuid
import { v4 as uuidv4, v7 as uuidv7 } from 'uuid';

console.log(uuidv4()); // random
console.log(uuidv7()); // timestamp-sortable

Python

Python's standard library has UUID support built in — no pip install needed.

import uuid

# UUID v4 (random)
print(uuid.uuid4())
# d9428888-122b-11e1-b85c-61cd3cbb3210

# UUID v1 (timestamp + node)
print(uuid.uuid1())

# UUID v5 (namespace + name — deterministic)
print(uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com'))
# cfbff0d1-9375-5685-968c-48ce8b15ae17

Generate multiple UUIDs:

import uuid

ids = [str(uuid.uuid4()) for _ in range(5)]
for id in ids:
    print(id)

Convert a UUID to different formats:

import uuid

u = uuid.uuid4()
print(u)           # 550e8400-e29b-41d4-a716-446655440000  (standard)
print(u.hex)       # 550e8400e29b41d4a716446655440000       (no hyphens)
print(u.int)       # 113059749145936325402354257176981405696 (integer)
print(u.bytes)     # raw 16 bytes

Command line

macOS and Linux:

uuidgen
# F9168C5E-CEB2-4FAA-B6BF-329BF39FA1E4

Lowercase (macOS outputs uppercase by default):

uuidgen | tr '[:upper:]' '[:lower:]'

Linux (alternative using /proc):

cat /proc/sys/kernel/random/uuid

Using Python as a one-liner (works anywhere Python is installed):

python3 -c "import uuid; print(uuid.uuid4())"

Bulk generation — 100 UUIDs, one per line:

python3 -c "import uuid; [print(uuid.uuid4()) for _ in range(100)]"

Use UUIDs as database primary keys

The tradeoff of UUID primary keys vs. sequential integers:

UUID advantages:

  • Generate IDs client-side without a database round-trip
  • Safe to merge data from multiple databases
  • Doesn't expose record counts or insertion order

UUID disadvantages:

  • 16 bytes vs 4–8 bytes for integers — larger indexes
  • Random UUIDs (v4) fragment B-tree indexes, causing slower inserts at scale
  • Not human-readable — harder to debug

The v7 solution: UUID v7 embeds a millisecond-precision timestamp in the first 48 bits, so rows inserted around the same time have adjacent UUIDs. This preserves B-tree locality and makes indexes perform closer to sequential integers, while keeping the distribution benefits of UUIDs.

-- PostgreSQL (v17+)
SELECT gen_random_uuid();   -- v4
-- No native v7 yet; use the pg_uuidv7 extension

-- MySQL (8.0+)
SELECT UUID();              -- v1

Validating UUIDs

function isValidUUID(str) {
    return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(str);
}
import uuid

def is_valid_uuid(val: str) -> bool:
    try:
        uuid.UUID(val)
        return True
    except ValueError:
        return False

Key takeaways

  • Use crypto.randomUUID() in modern browsers and Node.js 14.17+ — no library needed.
  • Use uuid.uuid4() in Python — also in the standard library.
  • Use uuidgen in the terminal on macOS/Linux.
  • Prefer v4 for general use; prefer v7 if you need UUIDs to sort chronologically.
  • Never use Math.random() for UUID generation — use crypto.getRandomValues() or a proper library.