UUID v4 in JavaScript generieren — Anleitung
Nutze das kostenlose UUID v4 Generator direkt im Browser – keine Installation erforderlich.
UUID v4 Generator online testen →Jede JavaScript-Anwendung braucht irgendwann eindeutige Bezeichner — Session-Token, Datenbankzeilen, Idempotency-Keys für Payment-APIs, Correlation-IDs für verteiltes Tracing. Der einfachste Weg, UUID v4 in JavaScript zu generieren, ist heute crypto.randomUUID(): keine Abhängigkeiten, eine Zeile Code, kryptografisch sicher. UUID v4 ist weit verbreitet, weil keine Koordination zwischen Diensten nötig ist — Client und Server können IDs unabhängig voneinander ohne Kollisionsrisiko erzeugen. Dieser Leitfaden behandelt diese eingebaute API, das uuid npm-Paket und Validierung — alles auf Node.js 19+ und modernen Browsern. Für eine No-Code-Option erzeugt der UUID v4 Generator auf ToolDeck konforme Bezeichner sofort.
- ✓crypto.randomUUID() ist in Browsern und Node.js eingebaut — keine Abhängigkeiten, eine Zeile Code.
- ✓UUID v4 ist ein 128-Bit-Zufallsbezeichner: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx (y ist 8, 9, a oder b).
- ✓Validierung mit /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i — prüft Versions- und Varianten-Bits.
- ✓Das uuid npm-Paket ergänzt v1, v3, v5 und v7, wenn mehr als zufällige IDs benötigt werden.
- ✓Für Datenbankprimärschlüssel UUID v7 (zeitgeordnet) statt v4 (zufällig) bevorzugen, um Index-Fragmentierung zu reduzieren.
Was ist UUID v4?
Eine UUID (Universally Unique Identifier) Version 4 ist ein 128-Bit-Zufallsbezeichner, formatiert als 32 hexadezimale Ziffern, getrennt durch vier Bindestriche: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx. Die 4 an Position 15 markiert die Version. Das y-Zeichen an Position 20 ist eines von 8, 9, a oder b (die RFC-4122-Variante). Die verbleibenden 122 Bits sind zufällig. UUID v4 ist die häufigste Version in JavaScript-Anwendungen, da sie keine Koordination zwischen Systemen erfordert — IDs können unabhängig auf Client und Server generiert werden, ohne sich um Kollisionen sorgen zu müssen.
// Kein Bezeichner
const event = { action: "user.login", ts: 1711824000 };// Mit UUID v4
const event = {
id: "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
action: "user.login",
ts: 1711824000
};crypto.randomUUID() — Der native JavaScript-Ansatz
crypto.randomUUID() ist in Chrome 92+, Firefox 95+, Safari 15.4+ und Node.js 19+ verfügbar (mit experimenteller Unterstützung ab Node.js 14.17.0 über globalThis.crypto). Die Funktion gibt einen 36-stelligen UUID-v4-String in Kleinbuchstaben zurück. Im Browser-JavaScript ist kein Import erforderlich. In Node.js kann sie direkt am globalen crypto-Objekt aufgerufen oder explizit aus dem node:crypto-Modul importiert werden.
// Funktioniert in jedem modernen Browser — kein Build-Schritt, kein Bundler
const requestId = crypto.randomUUID();
console.log(requestId);
// "3e7f1a92-4b0c-4d8e-9f12-7a6b3c8d5e1f"
// Überall verwenden, wo ein eindeutiger Bezeichner benötigt wird
const telemetryEvent = {
event_id: crypto.randomUUID(),
action: "checkout.started",
session_id: crypto.randomUUID(),
timestamp: Date.now(),
cart_total_cents: 14999,
};
console.log(JSON.stringify(telemetryEvent, null, 2));// Ansatz 1: globales crypto (Node.js 19+)
const orderId = crypto.randomUUID();
console.log(orderId);
// "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
// Ansatz 2: expliziter Import aus node:crypto
import { randomUUID } from 'node:crypto';
const correlationId = randomUUID();
console.log(correlationId);
// "f7e6d5c4-b3a2-4190-8f7e-6d5c4b3a2190"Eine Feature-Erkennung von crypto.randomUUID lohnt sich, wenn der Code in älteren Browsern oder eingebetteten WebViews laufen könnte. Die Prüfung ist ein einfacher typeof-Guard:
function generateUUIDv4() {
// Prefer the native API when available
if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
return crypto.randomUUID();
}
// Manual fallback using getRandomValues (see next section)
const bytes = new Uint8Array(16);
crypto.getRandomValues(bytes);
// Set version (4) and variant (RFC 4122)
bytes[6] = (bytes[6] & 0x0f) | 0x40; // version 4
bytes[8] = (bytes[8] & 0x3f) | 0x80; // variant 10xx
const hex = [...bytes].map(b => b.toString(16).padStart(2, '0'));
return [
hex.slice(0, 4).join(''),
hex.slice(4, 6).join(''),
hex.slice(6, 8).join(''),
hex.slice(8, 10).join(''),
hex.slice(10, 16).join(''),
].join('-');
}
console.log(generateUUIDv4());
// "9b2e4f1a-7c3d-4e8f-a5b6-0d2c1e9f8a7b"crypto.randomUUID() immer verfügbar. Auf unsicheren HTTP-Seiten wird in manchen Browsern ein Fehler geworfen. Wenn die Anwendung während der Entwicklung auf einfachem HTTP läuft, übernimmt der obige getRandomValues-Fallback diesen Fall.UUID v4 ohne Bibliothek generieren
Manchmal kann man sich nicht auf crypto.randomUUID() verlassen — vielleicht zielt man auf eine WebView ab, die die crypto-API entfernt, oder man möchte verstehen, was im Hintergrund passiert. Der manuelle Ansatz verwendet crypto.getRandomValues() (verfügbar seit IE 11), um 16 Bytes mit zufälligen Daten zu füllen, und wendet dann zwei Bitmask-Operationen an, um die Versions- und Variantenfelder zu setzen. Diese zwei Operationen sind der einzige Unterschied zwischen UUID v4 und einem reinen zufälligen Byte-String.
function uuidv4Manual() {
const bytes = new Uint8Array(16);
crypto.getRandomValues(bytes);
// Set version: bits 12–15 of byte 6 = 0100 (version 4)
bytes[6] = (bytes[6] & 0x0f) | 0x40;
// Set variant: bits 6–7 of byte 8 = 10 (RFC 4122)
bytes[8] = (bytes[8] & 0x3f) | 0x80;
const hex = [...bytes].map(b => b.toString(16).padStart(2, '0'));
return (
hex.slice(0, 4).join('') + '-' +
hex.slice(4, 6).join('') + '-' +
hex.slice(6, 8).join('') + '-' +
hex.slice(8, 10).join('') + '-' +
hex.slice(10, 16).join('')
);
}
const traceId = uuidv4Manual();
console.log(traceId);
// "e4d7c2a1-3f9b-48e5-a612-9d8c7b6a5f4e"
// Verify it passes UUID v4 validation
const UUID_V4_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
console.log(UUID_V4_RE.test(traceId)); // trueMath.random() zur UUID-Generierung. Die Funktion ist nicht kryptografisch sicher, ihr Ausgabeperiode ist zu kurz, und einige Engines erzeugen vorhersehbare Sequenzen. Verwende immer crypto.getRandomValues() oder crypto.randomUUID().Das uuid npm-Paket — Unterstützung mehrerer Versionen
Das uuid Paket auf npm war die erste Anlaufstelle für UUID-Generierung in JavaScript, bevor crypto.randomUUID() existierte. Es ist in drei Situationen sinnvoll: wenn andere UUID-Versionen als v4 benötigt werden (v1, v3, v5, v7), wenn Laufzeiten älter als Node.js 14.17.0 unterstützt werden müssen, oder wenn die validate und parse Hilfsfunktionen benötigt werden. Für einfaches UUID v4 auf einer modernen Laufzeit reicht die native API aus, und ich würde auf die Abhängigkeit verzichten.
npm install uuid
import { v4 as uuidv4, validate, version } from 'uuid';
// Generate a UUID v4
const paymentId = uuidv4();
console.log(paymentId);
// "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed"
// Validate any UUID string
console.log(validate(paymentId)); // true
console.log(validate("not-a-uuid")); // false
// Detect the version of a UUID
console.log(version(paymentId)); // 4
// Generate a batch for seeding a test database
const testAccounts = Array.from({ length: 5 }, () => ({
account_id: uuidv4(),
plan: "starter",
created_at: new Date().toISOString(),
}));
console.log(testAccounts);uuid-Paket verwendet intern crypto.getRandomValues() in Browsern und crypto.randomBytes() in Node.js, sodass die Entropiequelle identisch mit der nativen API ist. Der Unterschied liegt nur in den zusätzlichen Hilfsfunktionen und der Unterstützung mehrerer Versionen.Wer keinen Code schreiben möchte, kann den UUID v4 Generator verwenden — er erzeugt RFC-4122-konforme v4-Bezeichner direkt im Browser mit einem Klick.
Deterministische UUIDs — UUID v5 aus einem String generieren
UUID v4 ist per Definition zufällig — zweimaliges Aufrufen ergibt immer unterschiedliche Ergebnisse. Manchmal braucht man das Gegenteil: Derselbe Eingabe-String soll immer dieselbe UUID erzeugen. Genau das leistet UUID v5. Es hasht eine Namespace-UUID und einen Eingabe-String mit SHA-1 und formatiert das Ergebnis als UUID. Gleicher Namespace + gleicher Input = gleiche Ausgabe, jedes Mal, auf jedem Rechner. Das ist nützlich, um stabile IDs aus URLs, E-Mail-Adressen oder beliebigen Strings abzuleiten, die eine Ressource bereits identifizieren.
import { v5 as uuidv5 } from 'uuid';
// Built-in namespace for URLs (RFC 4122)
const URL_NAMESPACE = uuidv5.URL;
// "6ba7b811-9dad-11d1-80b4-00c04fd430c8"
// Same URL always produces the same UUID
const pageId1 = uuidv5("https://api.warehouse.dev/products/sku-7291", URL_NAMESPACE);
const pageId2 = uuidv5("https://api.warehouse.dev/products/sku-7291", URL_NAMESPACE);
console.log(pageId1 === pageId2); // true
console.log(pageId1);
// "a6e4e1c0-7e23-5d3b-8f14-9c2a1b3d5e7f"
// Custom namespace for your application
const APP_NAMESPACE = "f47ac10b-58cc-4372-a567-0e02b2c3d479";
const tenantId = uuidv5("acme-corp", APP_NAMESPACE);
console.log(tenantId);
// "d4735e3a-265b-564e-8f32-7a1b2c3d4e5f"Kurze Anmerkung: UUID v3 macht dasselbe, aber mit MD5 statt SHA-1. Für neue Projekte wird v5 empfohlen. MD5 hat bekannte Kollisionsschwächen, und obwohl das für die ID-Generierung nicht viel ausmacht, gibt es keinen Grund, es gegenüber SHA-1 zu wählen, wenn beide verfügbar sind.
crypto.randomUUID() und verwandte APIs — Referenz
Die native crypto.randomUUID() benötigt keine Argumente — sie gibt einen String zurück und nichts weiter. Verwende sie, wenn RFC-4122-konforme Bezeichner ohne Abhängigkeiten benötigt werden. Wenn statt eines formatierten UUID-Strings rohe zufällige Bytes benötigt werden — etwa zum Befüllen eines typisierten Arrays oder zur Schlüsselableitung — greife direkt auf crypto.getRandomValues() zurück. Die für UUID-Arbeit relevanten verwandten APIs sind unten aufgeführt.
Aufschlüsselung des UUID-v4-Regex-Musters:
UUID v4 mit Regex validieren
Die Validierung, ob ein String eine korrekte UUID v4 ist, taucht ständig auf — eingehende API-Anfrage-Bodies, URL-Parameter, Webhook-Payloads. Ein selbst geschriebener Regex ist die richtige Wahl, wenn keine Abhängigkeiten gewünscht werden und nur v4 validiert wird. Wer bereits das uuid Paket verwendet, sollte dessen validate() Export bevorzugen — er behandelt alle UUID-Versionen und ist weniger fehleranfällig als das Pflegen eines eigenen Musters. Der Regex /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i prüft sowohl das Versions-Nibble (muss 4 sein) als auch das Varianten-Nibble (muss 8, 9, a oder b sein). Verwende RegExp.prototype.test() für Boolean-Prüfungen und .match() wenn eine UUID aus umgebendem Text extrahiert werden soll.
const UUID_V4_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
function isUUIDv4(str) {
return UUID_V4_RE.test(str);
}
// Valid UUID v4
console.log(isUUIDv4("9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d")); // true
// UUID v1 — version nibble is 1, not 4
console.log(isUUIDv4("550e8400-e29b-11d4-a716-446655440000")); // false
// UUID v7 — version nibble is 7
console.log(isUUIDv4("018e4a0c-5b3f-7d12-8a9b-0c1d2e3f4a5b")); // false
// Malformed strings
console.log(isUUIDv4("not-a-uuid")); // false
console.log(isUUIDv4("")); // false
console.log(isUUIDv4("9b1deb4d3b7d4bad9bdd2b0d7b3dcb6d")); // false (no hyphens)
// Extract UUID from a larger string
const logLine = 'Request req_id=9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d failed with 503';
const match = logLine.match(/[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/i);
console.log(match?.[0]);
// "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"UUIDs aus Datei und API-Antwort generieren und zuweisen
In der Praxis wird crypto.randomUUID() selten isoliert aufgerufen. Zwei Muster tauchen ständig auf: Datensätzen IDs zuweisen, bevor sie in eine Datenbank geschrieben werden, und ausgehenden API-Anfragen Correlation-IDs anhängen, um eine Anfrage in den Logs über Dienste hinweg verfolgen zu können.
NDJSON-Datei lesen → UUIDs zuweisen → zurückschreiben
import { readFileSync, writeFileSync } from 'node:fs';
import { randomUUID } from 'node:crypto';
function assignIds(inputPath, outputPath) {
const lines = readFileSync(inputPath, 'utf-8')
.split('\n')
.filter(line => line.trim());
const records = lines.map(line => {
try {
const record = JSON.parse(line);
if (!record.id) {
record.id = randomUUID();
}
return JSON.stringify(record);
} catch (err) {
console.error(`Skipping malformed line: ${err.message}`);
return null;
}
}).filter(Boolean);
writeFileSync(outputPath, records.join('\n') + '\n');
console.log(`Assigned IDs to ${records.length} records → ${outputPath}`);
}
assignIds('warehouse-products.ndjson', 'warehouse-products-with-ids.ndjson');
// Assigned IDs to 1284 records → warehouse-products-with-ids.ndjsonCorrelation-ID an ausgehende API-Anfrage anhängen
import { randomUUID } from 'node:crypto';
async function createShipment(orderPayload) {
const correlationId = randomUUID();
try {
const response = await fetch('https://api.logistics.dev/v2/shipments', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Correlation-ID': correlationId,
'X-Idempotency-Key': randomUUID(),
},
body: JSON.stringify(orderPayload),
});
if (!response.ok) {
const errorBody = await response.text();
throw new Error(`Shipment API returned ${response.status}: ${errorBody}`);
}
const result = await response.json();
console.log(`Shipment created: ${result.shipment_id} (correlation: ${correlationId})`);
return result;
} catch (err) {
console.error(`[correlation:${correlationId}] Shipment failed: ${err.message}`);
throw err;
}
}
await createShipment({
order_id: "ord_8a3f91bc",
destination: { city: "Berlin", state: "BE", zip: "10115" },
items: [{ sku: "WH-7291", quantity: 2, weight_kg: 1.4 }],
});UUID-Generierung in der Kommandozeile
Manchmal wird kein Skript benötigt. Node.js kann eine UUID direkt in der Kommandozeile generieren, was praktisch für Shell-Skripte, CI-Pipelines und schnelle Ad-hoc-Tests ist. Das -e-Flag wertet einen einzelnen Ausdruck aus.
# Single UUID node -e "console.log(crypto.randomUUID())" # 3e7f1a92-4b0c-4d8e-9f12-7a6b3c8d5e1f # Five UUIDs at once node -e "for(let i=0;i<5;i++) console.log(crypto.randomUUID())" # Generate and assign to a shell variable export REQUEST_ID=$(node -e "process.stdout.write(crypto.randomUUID())") echo "Request ID: $REQUEST_ID" # Use npx uuid (if you have the package installed globally or want a one-off) npx uuid v4 # 1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed
# Open any browser DevTools console and type: crypto.randomUUID() # "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"
uuidgen auf macOS und den meisten Linux-Distributionen vorinstalliert. Auf modernen Systemen generiert es standardmäßig UUID v4.Hochleistungsalternative — nanoid
Wenn Tausende von IDs pro Sekunde generiert werden und das 36-stellige UUID-Format keine feste Anforderung ist, sollte man nanoid in Betracht ziehen. Es ist doppelt so schnell wie uuid.v4(), erzeugt standardmäßig eine 21-stellige URL-sichere ID und wiegt nach Minifizierung etwa 1 KB. Die Ausgabe ist keine UUID — es ist eine ID mit eigenem Alphabet — daher nicht dort verwenden, wo RFC-4122-Konformität erforderlich ist (UUID-Datenbankspalten, APIs, die das UUID-Format validieren, OpenTelemetry-Trace-IDs). Für interne Correlation-IDs, React-Komponentenschlüssel und URL-Slugs ist es jedoch gut geeignet.
npm install nanoid
import { nanoid, customAlphabet } from 'nanoid';
// Default: 21-char URL-safe ID (A-Za-z0-9_-)
const trackingCode = nanoid();
console.log(trackingCode);
// "V1StGXR8_Z5jdHi6B-myT"
// Custom length
const shortCode = nanoid(10);
console.log(shortCode);
// "IRFa-VaY2b"
// Custom alphabet — numbers only, 12 digits
const numericId = customAlphabet('0123456789', 12);
console.log(numericId());
// "839274651023"
// Custom alphabet — hex only, 32 chars (same entropy as UUID v4 without hyphens)
const hexId = customAlphabet('0123456789abcdef', 32);
console.log(hexId());
// "4f8a1b2c3d7e9f0a5b6c8d1e2f3a4b5c"Terminal-Ausgabe mit Syntaxhervorhebung
Das Debuggen UUID-lastiger Anwendungen bedeutet, Wände aus Hex-Strings im Terminal zu betrachten. Farb-Codierung hilft. Die chalk Bibliothek (oder das neuere eingebaute node:util styleText in Node.js 21.7+) ermöglicht das Hervorheben von UUIDs in der Log-Ausgabe, sodass sie sich vom umgebenden Text abheben.
import chalk from 'chalk';
import { randomUUID } from 'node:crypto';
function logEvent(action, metadata = {}) {
const eventId = randomUUID();
const timestamp = new Date().toISOString();
console.log(
chalk.gray(timestamp),
chalk.cyan(eventId),
chalk.white(action),
Object.keys(metadata).length
? chalk.dim(JSON.stringify(metadata))
: ''
);
}
logEvent('shipment.created', { order_id: 'ord_8a3f', carrier: 'fedex' });
logEvent('payment.captured', { amount_cents: 14999, currency: 'USD' });
logEvent('webhook.delivered', { endpoint: 'https://hooks.acme.dev/orders' });
// 2026-03-27T10:15:00.000Z a1b2c3d4-... shipment.created {"order_id":"ord_8a3f",...}Kurze eindeutige IDs in JavaScript generieren
Eine 36-stellige UUID ist manchmal zu lang — URL-Slugs, QR-Code-Daten, SMS-Nachrichten und eingebettete Hardware-Protokolle haben alle Längenbeschränkungen.
import { randomUUID } from 'node:crypto';
// 1. Strip hyphens from UUID v4 → 32-char hex string
const hex32 = randomUUID().replaceAll('-', '');
console.log(hex32);
// "3e7f1a924b0c4d8e9f127a6b3c8d5e1f" (32 chars)
// 2. Base64-encode 16 random bytes → 22-char string (URL-safe)
const bytes = new Uint8Array(16);
crypto.getRandomValues(bytes);
const base64Id = Buffer.from(bytes)
.toString('base64url')
.replace(/=+$/, '');
console.log(base64Id);
// "Pj8akksNTY6fEnarPIvR" (22 chars, 128 bits of entropy)
// 3. nanoid at custom length
import { nanoid } from 'nanoid';
const short12 = nanoid(12);
console.log(short12);
// "V1StGXR8_Z5j" (12 chars, ~71 bits of entropy)Die Kollisionswahrscheinlichkeits-Mathematik: Eine 12-stellige nanoid (Standard-Alphabet mit 64 Zeichen) liefert etwa 71 Bits Entropie. Bei 1.000 IDs pro Sekunde würde man etwa 116 Jahre benötigen, um eine 1-%-Kollisionswahrscheinlichkeit zu erreichen. Für die meisten Anwendungen ist das mehr als genug. Wenn Millionen von IDs pro Tag generiert werden, sollte man bei der vollständigen UUID bleiben oder nanoid mit mindestens 21 Zeichen verwenden.
UUID v7 — zeitgeordnete Alternative zu v4
UUID v7 (definiert in RFC 9562) bettet einen 48-Bit Unix-Millisekunden-Zeitstempel im ersten Segment ein, gefolgt von zufälligen Bits. Das Ergebnis ist eine UUID, die v4 ähnelt, aber chronologisch sortiert. Das macht sie zu einer besseren Wahl als v4 für Datenbankprimärschlüssel: Neue Zeilen landen immer am Ende des B-Tree-Index statt an zufälligen Positionen, was Page-Splits und Fragmentierung reduziert. In Projekten, bei denen zeitgeordnete IDs für eine Postgres-Tabelle benötigt werden, wechsle ich sofort zu v7 — der Indexperformance-Unterschied ist bei Scale messbar. Der UUID v7 Generator auf ToolDeck zeigt den eingebetteten Zeitstempel für jede v7-UUID.
import { v7 as uuidv7 } from 'uuid';
// Generate three UUID v7 values — notice they sort chronologically
const id1 = uuidv7();
const id2 = uuidv7();
const id3 = uuidv7();
console.log(id1);
// "018e4a0c-5b3f-7d12-8a9b-0c1d2e3f4a5b"
console.log(id2);
// "018e4a0c-5b40-7e34-9c2d-1e4f5a6b7c8d"
console.log(id3);
// "018e4a0c-5b41-7f56-ae3f-2a5b6c7d8e9f"
// They sort lexicographically by creation time
console.log([id3, id1, id2].sort());
// [id1, id2, id3] — chronological order preserved
// Use v4 for tokens where timing should not be leaked
import { v4 as uuidv4 } from 'uuid';
const sessionToken = uuidv4(); // fully random, no timing infouuid-Paket unterstützt v7 ab Version 9.0.0. Wer eine ältere Version verwendet, führt npm install uuid@latest zum Aktualisieren aus.UUID v4 im Browser ohne Build-Schritt
Kein Bundler, kein npm, kein Transpiler. Nur eine einfache HTML-Datei. Das ist der einfachstmögliche Weg, eine UUID in clientseitigem JavaScript zu generieren. Es funktioniert, weil crypto.randomUUID() eine eingebaute Browser-API ist.
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>UUID Generator</title></head>
<body>
<p>Your UUID: <strong id="output"></strong></p>
<button onclick="document.getElementById('output').textContent = crypto.randomUUID()">
Generate
</button>
<script>
// Generate one on page load
document.getElementById('output').textContent = crypto.randomUUID();
</script>
</body>
</html>Das ist die gesamte Datei. Keine CDN-Imports, keine Script-Tags für Bibliotheken. Für alles Komplexere — Batch-Generierung, Validierung, deterministische IDs — wird das uuid Paket oder der zuvor gezeigte manuelle Fallback benötigt. Aber für einen schnellen Prototyp oder ein internes Tool ist das alles, was man braucht.
Häufige Fehler
Das Math.random() UUID-Muster wurde öfter als mir lieb ist aus alten Blog-Posts in Produktionscode kopiert. Die Bugs, die diese Muster einführen, sind lautlos: kein Laufzeitfehler, nur subtil falsches Verhalten, das später unter Last oder in Security-Reviews auftaucht.
Problem: Math.random() ist nicht kryptografisch sicher. Die Ausgabe ist in manchen Engines vorhersehbar, und die geringe Entropie macht Kollisionen weitaus wahrscheinlicher als bei einem echten CSPRNG.
Lösung: Immer crypto.randomUUID() oder crypto.getRandomValues() verwenden. Beide nutzen den CSPRNG des Betriebssystems.
// INSECURE — predictable, low entropy
function badUuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(
/[xy]/g,
c => {
const r = Math.random() * 16 | 0;
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
}
);
}// SECURE — uses the OS CSPRNG
const id = crypto.randomUUID();
// Or if you need a manual fallback:
function secureUuid() {
const bytes = new Uint8Array(16);
crypto.getRandomValues(bytes);
bytes[6] = (bytes[6] & 0x0f) | 0x40;
bytes[8] = (bytes[8] & 0x3f) | 0x80;
const h = [...bytes].map(b => b.toString(16).padStart(2, '0'));
return `${h.slice(0,4).join('')}-${h.slice(4,6).join('')}-${h.slice(6,8).join('')}-${h.slice(8,10).join('')}-${h.slice(10).join('')}`;
}Problem: crypto.randomUUID() gibt Kleinbuchstaben-Hex zurück, aber UUIDs aus anderen Systemen (Datenbanken, APIs, Benutzereingaben) könnten Großbuchstaben verwenden. Direkter ===-Vergleich schlägt fehl, wenn die Schreibweise abweicht.
Lösung: Vor dem Vergleich beide Seiten auf Kleinbuchstaben normalisieren.
const fromApi = "9B1DEB4D-3B7D-4BAD-9BDD-2B0D7B3DCB6D"; // uppercase from API
const local = "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"; // lowercase from crypto
if (fromApi === local) { /* never runs */ }const fromApi = "9B1DEB4D-3B7D-4BAD-9BDD-2B0D7B3DCB6D";
const local = "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d";
if (fromApi.toLowerCase() === local.toLowerCase()) {
// matches correctly
}Problem: Einige UUID-Bibliotheken (besonders in anderen Sprachen) geben UUID-Objekte zurück. In JavaScript bricht das versehentliche Einwickeln eines UUID-Strings in ein Objekt Gleichheitsprüfungen, JSON-Serialisierung und Datenbankabfragen.
Lösung: UUIDs immer als einfache Strings speichern und weitergeben. Wenn eine Bibliothek ein Objekt zurückgibt, sofort .toString() aufrufen oder direkt auf die String-Eigenschaft zugreifen.
// Creating unnecessary wrapper
class UUID {
constructor(value) { this.value = value; }
}
const id = new UUID(crypto.randomUUID());
console.log(id === id); // true, but...
console.log(JSON.stringify({ id })); // {"id":{"value":"..."}}// Just use a string
const id = crypto.randomUUID();
console.log(JSON.stringify({ id }));
// {"id":"3e7f1a92-4b0c-4d8e-9f12-7a6b3c8d5e1f"}Problem: UUID v4 ist vollständig zufällig. Das Sortieren nach UUID v4 ergibt eine willkürliche Reihenfolge, keine Erstellungsreihenfolge. Das führt zu unvorhersehbarer Paginierung, verwirrenden Admin-Oberflächen und schlechter Datenbankindex-Performance.
Lösung: UUID v7 verwenden, wenn zeitgeordnete Bezeichner benötigt werden. UUID v4 für Token und Correlation-IDs behalten, wo die Sortierreihenfolge irrelevant ist.
// Bad: using v4 as a sortable primary key
const rows = [
{ id: crypto.randomUUID(), created: "2026-03-27" },
{ id: crypto.randomUUID(), created: "2026-03-26" },
];
rows.sort((a, b) => a.id.localeCompare(b.id));
// Sort order is random — NOT by creation dateimport { v7 as uuidv7 } from 'uuid';
// Good: v7 sorts by creation time
const rows = [
{ id: uuidv7(), created: "2026-03-27" },
{ id: uuidv7(), created: "2026-03-26" },
];
rows.sort((a, b) => a.id.localeCompare(b.id));
// Sort order matches creation timecrypto.randomUUID() vs uuid vs nanoid — Kurzvergleich
Für die meisten JavaScript-Projekte gilt: Verwende crypto.randomUUID() wenn nur UUID v4 benötigt wird und die Laufzeit neu genug ist. Greife auf das uuid Paket zurück, wenn v5 (deterministisch) oder v7 (zeitgeordnet) benötigt wird. Verwende nanoid wenn eine kurze, URL-sichere ID praktischer ist als eine 36-stellige UUID — aber beachte, dass nanoid-Ausgaben nicht UUID-konform sind und auf jedem System, das das RFC-4122-Format erwartet, die Validierung nicht bestehen.
Für eine No-Code-Alternative nutze den UUID v4 Generator um Bezeichner sofort im Browser zu erstellen. Um eine vorhandene UUID zu untersuchen, füge sie in den UUID Decoder ein, um Version, Variante und eingebettete Zeitstempeldaten zu sehen.
Häufig gestellte Fragen
Wie generiere ich eine UUID v4 in JavaScript?
Rufe crypto.randomUUID() in jedem modernen Browser (Chrome 92+, Firefox 95+, Safari 15.4+) oder Node.js 19+ auf. Die Funktion gibt einen Kleinbuchstaben-String wie "3e7f1a92-4b0c-4d8e-9f12-7a6b3c8d5e1f" zurück. Im Browser wird kein Import benötigt, da crypto ein eingebautes globales Objekt ist. In Node.js kannst du es auch explizit mit import { randomUUID } from "node:crypto" importieren. Für Laufzeiten älter als Node.js 19 war crypto.randomUUID() experimentell ab Node.js 14.17.0 verfügbar. Wer keinen Code schreiben möchte, kann den UUID v4 Generator unter /en/uuid/v4 verwenden.
const sessionId = crypto.randomUUID(); console.log(sessionId); // "3e7f1a92-4b0c-4d8e-9f12-7a6b3c8d5e1f"
Ist crypto.randomUUID() kryptografisch sicher?
Ja. crypto.randomUUID() verwendet denselben CSPRNG (kryptografisch sicherer Pseudozufallszahlengenerator) wie crypto.getRandomValues(). Die 122 zufälligen Bits in einer UUID v4 machen Kollisionen für praktische Zwecke vernachlässigbar — man müsste etwa 2,71 Quintillionen UUIDs generieren, bevor eine 50-%-Kollisionswahrscheinlichkeit erreicht wird. Die Entropie stammt aus der Zufallsquelle des Betriebssystems (/dev/urandom unter Linux, BCryptGenRandom unter Windows), nicht aus Math.random(), das explizit nicht kryptografisch sicher ist. UUID-v4-Werte sind daher sicher als Session-Token, CSRF-Token und andere sicherheitskritische Bezeichner einsetzbar. Verwende niemals Math.random()-basierte UUID-Generatoren in sicherheitsrelevanten Kontexten.
Kann ich UUID v4 als Datenbankprimärschlüssel verwenden?
Das ist möglich, aber es gibt einen erheblichen Performance-Kompromiss. UUID v4 ist vollständig zufällig, weshalb B-Tree-Indizes stark fragmentieren, da jede neue Zeile an einer zufälligen Position im Index eingefügt wird statt am Ende. Bei schreibintensiven Tabellen führt dies zu übermäßigen Page-Splits und Cache-Misses, was die INSERT- und Range-Scan-Performance verschlechtert. Wenn deine Datenbank es unterstützt (PostgreSQL, MySQL 8.0+, SQL Server), ist UUID v7 (zeitgeordnet) ein besserer Primärschlüssel, da neue Zeilen immer am Ende des Index angehängt werden. UUID v4 bleibt die richtige Wahl für Session-Token, OAuth-State-Parameter, Idempotency-Keys, Correlation-IDs und alle Felder, bei denen das Verstecken des Erstellungszeitpunkts erwünscht ist.
// UUID v4 — zufällig, nicht sortierbar
const correlationId = crypto.randomUUID();
// UUID v7 — zeitgeordnet, besser für DB-Primärschlüssel
import { v7 as uuidv7 } from 'uuid';
const rowId = uuidv7();Was ist der Unterschied zwischen UUID v4 und UUID v7?
UUID v4 füllt 122 Bits mit zufälligen Daten — jedes Segment ist effektiv Rauschen. UUID v7 (RFC 9562, veröffentlicht 2024) kodiert einen 48-Bit Unix-Millisekunden-Zeitstempel im ersten Segment, 12 Bits Submillisekunden-Präzision im zweiten Segment und zufällige Bits im Rest. Beide sind 128 Bits lang und verwenden dasselbe 36-stellige Bindestrischformat, sind also auf der Speicherebene austauschbar. UUID v7 ist lexikografisch nach Erstellungszeit sortierbar, was B-Tree-Indizes kompakt hält und Range-Abfragen über Zeitfenster effizient macht. Wähle UUID v4, wenn die ID nicht verraten soll, wann sie erstellt wurde — etwa bei öffentlichen Token, bei denen Timing-Informationen ausgenutzt werden könnten — und UUID v7 für Datenbankprimärschlüssel, Audit-Logs und Event-Streams, bei denen die chronologische Reihenfolge wichtig ist.
Wie validiere ich einen UUID-v4-String in JavaScript?
Prüfe gegen den Regex /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i. Das literale "4" an Position 15 (0-indiziert) bestätigt das Versions-Nibble; das Zeichen an Position 20 — eines von 8, 9, a oder b — kodiert die RFC-4122-Varianten-Bits. Dieser Regex lehnt UUID v1, v7 und jeden fehlerhaften String korrekt ab. Das Flag i macht ihn case-insensitiv, sodass Großbuchstaben-Hex-Ziffern aus anderen Systemen ohne Normalisierung validiert werden. Wenn du nur prüfen möchtest, ob ein String eine beliebige gültige UUID ist (unabhängig von der Version), verwende stattdessen das lockerere Muster /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.
const UUID_V4_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
UUID_V4_RE.test("550e8400-e29b-41d4-a716-446655440000"); // true
UUID_V4_RE.test("550e8400-e29b-11d4-a716-446655440000"); // false (v1)
UUID_V4_RE.test("not-a-uuid"); // falseWie generiere ich eine kurze eindeutige ID in JavaScript?
Entferne die Bindestriche aus einer UUID v4, um einen 32-stelligen Hex-String zu erhalten: crypto.randomUUID().replaceAll("-", ""). Für etwas noch Kürzeres verwende nanoid, das standardmäßig eine 21-stellige URL-sichere ID (A–Z, a–z, 0–9, _ und -) mit vergleichbarer Kollisionsresistenz wie eine vollständige UUID erzeugt. Der Kompromiss ist einfach: Kürzere IDs haben eine höhere Kollisionswahrscheinlichkeit, aber nanoid mit 21 Zeichen liefert trotzdem 126 Bits Entropie, was für praktisch jede reale Anwendung mehr als ausreichend ist. Für URL-Slugs und QR-Code-Nutzlasten kann man mit nanoid bis auf 10–12 Zeichen heruntergehen, bevor die Kollisionswahrscheinlichkeit bei typischen Generierungsraten relevant wird. Vermeide es, eine rohe UUID in Base64 zu kodieren und dann abzuschneiden — das Abschneiden zerstört die statistische Unabhängigkeit der Bits und macht Kollisionen schwerer einzuschätzen.
// 32-stelliger Hex-String aus UUID v4
const hexId = crypto.randomUUID().replaceAll('-', '');
// "3e7f1a924b0c4d8e9f127a6b3c8d5e1f"
// 21-stellige URL-sichere ID via nanoid
import { nanoid } from 'nanoid';
const shortId = nanoid();
// "V1StGXR8_Z5jdHi6B-myT"Verwandte Tools
Sophie is a full-stack developer focused on TypeScript across the entire stack — from React frontends to Express and Fastify backends. She has a particular interest in type-safe API design, runtime validation, and the patterns that make large JavaScript codebases stay manageable. She writes about TypeScript idioms, Node.js internals, and the ever-evolving JavaScript module ecosystem.
Marcus specialises in JavaScript performance, build tooling, and the inner workings of the V8 engine. He has spent years profiling and optimising React applications, working on bundler configurations, and squeezing every millisecond out of critical rendering paths. He writes about Core Web Vitals, JavaScript memory management, and the tools developers reach for when performance really matters.