UUID v4 w JavaScript — crypto.randomUUID()

·TypeScript & Full-stack Developer·Sprawdzono przezMarcus Webb·Opublikowano

Użyj darmowego Generator UUID v4 bezpośrednio w przeglądarce — bez instalacji.

Wypróbuj Generator UUID v4 online →

Każda aplikacja JavaScript prędzej czy później potrzebuje unikalnych identyfikatorów — tokenów sesji, wierszy bazy danych, kluczy idempotentności dla API płatności, identyfikatorów korelacji do śledzenia rozproszonych systemów. Najprostszy sposób na generowanie UUID v4 w JavaScript to dziś crypto.randomUUID(): zero zależności, jedna linia, kryptograficznie bezpieczne. UUID v4 jest powszechnie stosowane właśnie dlatego, że nie wymaga koordynacji między serwisami — klient i serwer mogą generować identyfikatory niezależnie bez ryzyka kolizji. Ten przewodnik omawia to wbudowane API, pakiet uuid npm, walidację — wszystko na Node.js 19+ i nowoczesnych przeglądarkach. Dla opcji bez kodu, Generator UUID v4 na ToolDeck tworzy zgodne identyfikatory natychmiast.

  • crypto.randomUUID() jest wbudowane w przeglądarki i Node.js — zero zależności, jedna linia kodu.
  • UUID v4 to 128-bitowy losowy identyfikator: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx (y to 8, 9, a lub b).
  • Waliduj wyrażeniem /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i — sprawdza bity wersji i wariantu.
  • Pakiet uuid npm dodaje obsługę v1, v3, v5 i v7, gdy potrzebujesz więcej niż losowe identyfikatory.
  • Dla kluczy głównych bazy danych preferuj UUID v7 (czasowo uporządkowane) zamiast v4 (losowego), by zmniejszyć fragmentację indeksu.

Czym jest UUID v4?

UUID (Universally Unique Identifier) w wersji 4 to 128-bitowy losowy identyfikator sformatowany jako 32 cyfry szesnastkowe oddzielone czterema myślnikami: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx. Znak 4 na pozycji 15 oznacza wersję. Znak y na pozycji 20 to jeden z 8, 9, a lub b (wariant RFC 4122). Pozostałe 122 bity są losowe. UUID v4 jest najczęstszą wersją w aplikacjach JavaScript, ponieważ nie wymaga koordynacji między systemami — identyfikatory można generować niezależnie po stronie klienta i serwera bez obaw o kolizje.

Before · javascript
After · javascript
// Brak identyfikatora
const event = { action: "user.login", ts: 1711824000 };
// Z UUID v4
const event = {
  id: "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
  action: "user.login",
  ts: 1711824000
};

crypto.randomUUID() — natywne podejście w JavaScript

crypto.randomUUID() jest dostępne w Chrome 92+, Firefox 95+, Safari 15.4+ i Node.js 19+ (z eksperymentalną obsługą od Node.js 14.17.0 poprzez globalThis.crypto). Zwraca małoliterowy 36-znakowy ciąg UUID v4. W przeglądarkowym JavaScript nie jest wymagany żaden import. W Node.js możesz wywołać to bezpośrednio na globalnym obiekcie cryptolub jawnie zaimportować z modułu node:crypto.

JavaScript — przeglądarka (zero importów)
// Działa w każdej nowoczesnej przeglądarce — bez kroku budowania, bez bundlera
const requestId = crypto.randomUUID();
console.log(requestId);
// "3e7f1a92-4b0c-4d8e-9f12-7a6b3c8d5e1f"

// Użyj wszędzie tam, gdzie potrzebujesz unikalnego identyfikatora
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));
Node.js — dwa równoważne podejścia
// Podejście 1: globalny crypto (Node.js 19+)
const orderId = crypto.randomUUID();
console.log(orderId);
// "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"

// Podejście 2: jawny import z node:crypto
import { randomUUID } from 'node:crypto';
const correlationId = randomUUID();
console.log(correlationId);
// "f7e6d5c4-b3a2-4190-8f7e-6d5c4b3a2190"

Warto wykrywać obecność crypto.randomUUID jeśli kod może działać w starszych przeglądarkach lub osadzonych WebView. Sprawdzenie sprowadza się do jednej instrukcji typeof:

JavaScript — wykrywanie funkcji z awaryjnym mechanizmem
function generateUUIDv4() {
  // Preferuj natywne API, gdy dostępne
  if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
    return crypto.randomUUID();
  }

  // Ręczna rezerwa z getRandomValues (patrz następna sekcja)
  const bytes = new Uint8Array(16);
  crypto.getRandomValues(bytes);

  // Ustaw wersję (4) i wariant (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"
Uwaga:W bezpiecznych kontekstach (strony HTTPS, localhost, rozszerzenia przeglądarki), crypto.randomUUID() jest zawsze dostępne. W niektórych przeglądarkach zgłasza wyjątek na nieszyfrowanych stronach HTTP. Jeśli aplikacja działa na zwykłym HTTP podczas developmentu, powyższy mechanizm awaryjny getRandomValues obsługuje ten przypadek.

Generowanie UUID v4 bez biblioteki

Czasem nie można polegać na crypto.randomUUID() — być może celujesz w WebView, który usuwa API crypto, albo chcesz zrozumieć, co dzieje się pod maską. Ręczne podejście używa crypto.getRandomValues() (dostępnego od IE 11) do wypełnienia 16 bajtów losowymi danymi, a następnie stosuje dwie operacje bitmaskowe, by ustawić pola wersji i wariantu. Te dwie operacje to jedyna różnica między UUID v4 a czystym losowym ciągiem bajtów.

JavaScript — ręczny UUID v4 z getRandomValues
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"

// Zweryfikuj, czy przechodzi walidację UUID v4
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)); // true
Ostrzeżenie:Nigdy nie używaj Math.random() do generowania UUID. Nie jest kryptograficznie bezpieczne, jego okres wyjściowy jest zbyt krótki, a niektóre silniki generują przewidywalne sekwencje. Zawsze używaj crypto.getRandomValues() lub crypto.randomUUID().

Pakiet uuid npm — obsługa wielu wersji

Pakiet uuid na npm był domyślną biblioteką UUID dla JavaScript, zanim powstało crypto.randomUUID(). Nadal ma sens w trzech sytuacjach: gdy potrzebujesz wersji UUID innych niż v4 (v1, v3, v5, v7), celujesz w środowiska uruchomieniowe starsze niż Node.js 14.17.0 lub chcesz mieć funkcje narzędziowe validate i parse. Dla zwykłego UUID v4 na nowoczesnym środowisku natywne API wystarczy i pominąłbym tę zależność.

bash — instalacja
npm install uuid
JavaScript — pakiet uuid do generowania v4
import { v4 as uuidv4, validate, version } from 'uuid';

// Generuj UUID v4
const paymentId = uuidv4();
console.log(paymentId);
// "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed"

// Waliduj dowolny ciąg UUID
console.log(validate(paymentId));    // true
console.log(validate("not-a-uuid")); // false

// Wykryj wersję UUID
console.log(version(paymentId));     // 4

// Generuj partię do wypełnienia testowej bazy danych
const testAccounts = Array.from({ length: 5 }, () => ({
  account_id: uuidv4(),
  plan: "starter",
  created_at: new Date().toISOString(),
}));
console.log(testAccounts);
Uwaga:Pakiet uuid wewnętrznie używa crypto.getRandomValues() w przeglądarkach i crypto.randomBytes() w Node.js, więc źródło entropii jest identyczne jak w natywnym API. Różnica polega jedynie na dodatkowych funkcjach narzędziowych i obsłudze wielu wersji.

Jeśli wolisz nie pisać kodu, wypróbuj Generator UUID v4 — generuje zgodne z RFC 4122 identyfikatory v4 bezpośrednio w przeglądarce jednym kliknięciem.

Deterministyczne UUID — generowanie UUID v5 z ciągu znaków

UUID v4 jest z definicji losowe — każde wywołanie daje inny wynik. Czasem potrzebne jest coś przeciwnego: ten sam ciąg wejściowy powinien zawsze generować ten sam UUID. To właśnie robi UUID v5. Hashuje przestrzeń nazw UUID i ciąg wejściowy za pomocą SHA-1, a następnie formatuje wynik jako UUID. Ten sam namespace + te same dane wejściowe = ten sam wynik, za każdym razem, na każdej maszynie. Jest to przydatne do uzyskiwania stabilnych identyfikatorów z adresów URL, adresów e-mail lub dowolnego ciągu, który już identyfikuje zasób.

JavaScript — uuid v5 dla deterministycznych ID
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"

Krótka uwaga: UUID v3 robi to samo, ale z MD5 zamiast SHA-1. Dla nowych projektów preferuj v5. MD5 ma znane słabości kolizyjne i choć nie ma to większego znaczenia przy generowaniu identyfikatorów, nie ma powodu, by wybierać MD5 nad SHA-1, gdy oba są dostępne.

Dokumentacja crypto.randomUUID() i powiązanych API

Natywna funkcja crypto.randomUUID() nie przyjmuje żadnych argumentów — zwraca ciąg i nic więcej. Użyj jej, gdy potrzebujesz identyfikatorów zgodnych z RFC 4122 bez żadnych zależności. Gdy zamiast sformatowanego ciągu UUID potrzebujesz surowych losowych bajtów — na przykład do wypełnienia tablicy typowanej lub wyprowadzenia klucza — sięgnij bezpośrednio po crypto.getRandomValues(). Poniżej wymienione są powiązane API istotne przy pracy z UUID.

Właściwość / Metoda
Typ zwracany
Opis
crypto.randomUUID()
string
Zwraca 36-znakowy ciąg UUID v4 w małych literach szesnastkowych z myślnikami
crypto.getRandomValues(arr)
TypedArray
Wypełnia tablicę typowaną kryptograficznie losowymi wartościami — podstawa ręcznego generowania UUID
URL.createObjectURL(blob)
string
Generuje unikalny URL blobu (nie UUID, ale czasem mylony z nim)

Szczegółowy opis wzorca regex dla UUID v4:

Segment
Wzorzec
Znaczenie
[0-9a-f]{8}
xxxxxxxx
Pierwsze 8 cyfr szesnastkowych — 32 losowe bity
[0-9a-f]{4}
xxxx
Kolejne 4 cyfry szesnastkowe — 16 losowych bitów
4[0-9a-f]{3}
4xxx
Nibble wersji stałej 4, po nim 12 losowych bitów
[89ab][0-9a-f]{3}
yxxx
Nibble wariantu: 8, 9, a lub b — po nim 12 losowych bitów
[0-9a-f]{12}
xxxxxxxxxxxx
Ostatnie 12 cyfr szesnastkowych — 48 losowych bitów

Walidacja UUID v4 za pomocą wyrażenia regularnego

Sprawdzanie, czy ciąg jest poprawnym UUID v4, pojawia się bardzo często — w treściach żądań API, parametrach URL, ładunkach webhooków. Ręcznie napisane wyrażenie regularne to właściwy wybór, gdy chcesz zerowych zależności i walidajesz tylko v4. Jeśli już używasz pakietu uuid, preferuj jego eksport validate() — obsługuje wszystkie wersje UUID i jest mniej podatny na błędy niż utrzymywanie niestandardowego wzorca. Wyrażenie regularne /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i sprawdza zarówno nibble wersji (musi być 4), jak i nibble wariantu (musi być 8, 9, a lub b). Użyj RegExp.prototype.test() do sprawdzenia boolowskiego i .match() gdy musisz wyodrębnić UUID z otaczającego tekstu.

JavaScript — pomocnik do walidacji UUID v4
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);
}

// Poprawny UUID v4
console.log(isUUIDv4("9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d")); // true

// UUID v1 — nibble wersji to 1, nie 4
console.log(isUUIDv4("550e8400-e29b-11d4-a716-446655440000")); // false

// UUID v7 — nibble wersji to 7
console.log(isUUIDv4("018e4a0c-5b3f-7d12-8a9b-0c1d2e3f4a5b")); // false

// Zniekształcone ciągi
console.log(isUUIDv4("not-a-uuid"));           // false
console.log(isUUIDv4(""));                      // false
console.log(isUUIDv4("9b1deb4d3b7d4bad9bdd2b0d7b3dcb6d")); // false (brak myślników)

// Wyodrębnij UUID z większego ciągu
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"

Generowanie i przypisywanie UUID z pliku i odpowiedzi API

W praktyce rzadko wywołujesz crypto.randomUUID() w izolacji. Dwa wzorce pojawiają się bardzo często: przypisywanie identyfikatorów do rekordów przed zapisaniem ich do bazy danych oraz dołączanie identyfikatorów korelacji do wychodzących żądań API, by móc śledzić żądania między serwisami w logach.

Odczyt pliku NDJSON → przypisanie UUID → zapis z powrotem

Node.js — przypisywanie UUID do rekordów z pliku
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.ndjson

Dołączanie identyfikatora korelacji do wychodzącego żądania API

Node.js — identyfikator korelacji do śledzenia rozproszonych systemów
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: "Warszawa", state: "MZ", zip: "00-001" },
  items: [{ sku: "WH-7291", quantity: 2, weight_kg: 1.4 }],
});

Generowanie UUID z wiersza poleceń

Nie zawsze potrzebujesz skryptu. Node.js może wygenerować UUID bezpośrednio z wiersza poleceń, co jest przydatne w skryptach powłoki, pipeline'ach CI i szybkich testach ad hoc. Flaga -e wykonuje pojedyncze wyrażenie.

bash — generowanie UUID z wiersza poleceń
# Pojedynczy UUID
node -e "console.log(crypto.randomUUID())"
# 3e7f1a92-4b0c-4d8e-9f12-7a6b3c8d5e1f

# Pięć UUID naraz
node -e "for(let i=0;i<5;i++) console.log(crypto.randomUUID())"

# Generuj i przypisz do zmiennej powłoki
export REQUEST_ID=$(node -e "process.stdout.write(crypto.randomUUID())")
echo "Request ID: $REQUEST_ID"

# Użyj npx uuid (jeśli masz pakiet zainstalowany globalnie lub jednorazowo)
npx uuid v4
# 1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed
bash — generowanie UUID w konsoli przeglądarki (bez Node.js)
# Otwórz DevTools dowolnej przeglądarki i wpisz:
crypto.randomUUID()
# "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"
Uwaga:Jeśli potrzebujesz UUID w pipeline CI i Node.js nie jest dostępny, uuidgen jest preinstalowany na macOS i większości dystrybucji Linuksa. Na nowoczesnych systemach domyślnie generuje UUID v4.

Wysoko wydajna alternatywa — nanoid

Jeśli generujesz tysiące identyfikatorów na sekundę, a 36-znakowy format UUID nie jest twardym wymogiem, rozważ nanoid. Jest 2x szybszy niż uuid.v4(), domyślnie generuje 21-znakowy identyfikator URL-safe i waży około 1 KB po minifikacji. Wyjście nie jest UUID — to identyfikator z niestandardowym alfabetem — więc nie używaj go tam, gdzie wymagana jest zgodność z RFC 4122 (kolumny UUID w bazie danych, API walidujące format UUID, identyfikatory trace w OpenTelemetry). Ale dla wewnętrznych identyfikatorów korelacji, kluczy komponentów React i slugów URL to dobry wybór.

bash — instalacja nanoid
npm install nanoid
JavaScript — nanoid dla krótkich unikalnych ID
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"

Wyróżnianie składni w terminalu

Debugowanie aplikacji opartych na UUID oznacza wpatrywanie się w ściany ciągów szesnastkowych w terminalu. Kolorowanie pomaga. Biblioteka chalk (lub nowszy wbudowany node:util styleText w Node.js 21.7+) pozwala wyróżniać UUID w wyjściu logów, by wyróżniały się na tle otaczającego tekstu.

Node.js — kolorowe wyjście UUID z chalk
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",...}
Ostrzeżenie:Sekwencje escape kolorów psują pliki logów i łamią parsery JSON. Używaj chalk lub styleText tylko do wyjścia terminalowego, które człowiek czyta bezpośrednio. Dla ustrukturyzowanych logów trafiających do pliku lub agregatora logów, używaj zwykłego JSON.

Generowanie krótkich unikalnych identyfikatorów w JavaScript

36-znakowy UUID jest czasem zbyt długi — slugi URL, dane kodu QR, wiadomości SMS i protokoły osadzonego sprzętu mają ograniczenia długości.

JavaScript — trzy techniki tworzenia krótszych identyfikatorów
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)

Matematyka prawdopodobieństwa kolizji: 12-znakowy nanoid (domyślny alfabet 64 znaków) daje około 71 bitów entropii. Przy 1 000 identyfikatorach na sekundę potrzeba około 116 lat, by osiągnąć 1% prawdopodobieństwo kolizji. Dla większości aplikacji to więcej niż wystarczające. Jeśli generujesz miliony identyfikatorów dziennie, zostań przy pełnym UUID lub używaj nanoid z co najmniej 21 znakami.

UUID v7 — czasowo uporządkowana alternatywa dla v4

UUID v7 (zdefiniowany w RFC 9562) osadza 48-bitowy uniksowy znacznik czasu w milisekundach w pierwszym segmencie, po którym następują losowe bity. W efekcie powstaje UUID podobny do v4, ale sortowany chronologicznie. Sprawia to, że jest lepszym wyborem niż v4 dla kluczy głównych baz danych: nowe wiersze zawsze trafiają na koniec indeksu B-drzewa zamiast w losowe miejsca, co zmniejsza podziały stron i fragmentację. W projektach, gdzie potrzebuję czasowo uporządkowanych identyfikatorów dla tabeli Postgres, od razu przechodzę na v7 — różnica wydajności indeksu jest mierzalna przy skali. Generator UUID v7 na ToolDeck pokazuje osadzony znacznik czasu dla każdego UUID v7.

JavaScript — UUID v7 z pakietem 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 info
Uwaga:Pakiet uuid obsługuje v7 od wersji 9.0.0. Jeśli korzystasz ze starszej wersji, uruchom npm install uuid@latest, aby zaktualizować.

UUID v4 w przeglądarce bez kroku budowania

Bez bundlera, bez npm, bez transpilatora. Tylko zwykły plik HTML. To najprostszy możliwy sposób generowania UUID w JavaScripcie po stronie klienta. Działa, bo crypto.randomUUID() jest wbudowanym API przeglądarki.

HTML — minimalny generator UUID w przeglądarce
<!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>

To cały plik. Brak importów CDN, brak tagów script ładujących biblioteki. Do bardziej złożonych zadań — generowania wsadowego, walidacji, deterministycznych identyfikatorów — będziesz potrzebować pakietu uuid lub ręcznej rezerwy pokazanej wcześniej. Ale do szybkiego prototypu lub wewnętrznego narzędzia to wszystko, czego potrzebujesz.

Typowe błędy

Wzorzec UUID oparty na Math.random() kopiowany ze starych wpisów blogowych do kodu produkcyjnego zdarza się częściej, niż chciałbym przyznać. Błędy, które te wzorce wprowadzają, są ciche: brak błędu runtime, tylko subtelnie nieprawidłowe zachowanie ujawniające się później pod obciążeniem lub podczas przeglądu bezpieczeństwa.

Używanie Math.random() do generowania UUID

Problem: Math.random() nie jest kryptograficznie bezpieczne. Jego wyjście jest przewidywalne w niektórych silnikach, a niska entropia sprawia, że kolizje są znacznie bardziej prawdopodobne niż w przypadku właściwego CSPRNG.

Rozwiązanie: Zawsze używaj crypto.randomUUID() lub crypto.getRandomValues(). Oba korzystają z CSPRNG systemu operacyjnego.

Before · JavaScript
After · JavaScript
// 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('')}`;
}
Porównywanie UUID z uwzględnieniem wielkości liter

Problem: crypto.randomUUID() zwraca małe litery szesnastkowe, ale UUID z innych systemów (baz danych, API, danych użytkownika) mogą używać wielkich liter. Bezpośrednie porównanie === kończy się niepowodzeniem, gdy wielkość liter się różni.

Rozwiązanie: Przed porównaniem znormalizuj obie strony do małych liter.

Before · JavaScript
After · JavaScript
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
}
Przechowywanie UUID jako obiektów zamiast ciągów

Problem: Niektóre biblioteki UUID (zwłaszcza w innych językach) zwracają obiekty UUID. W JavaScript przypadkowe opakowanie ciągu UUID w obiekt psuje porównania równości, serializację JSON i zapytania do bazy danych.

Rozwiązanie: Zawsze przechowuj i przekazuj UUID jako zwykłe ciągi. Jeśli biblioteka zwraca obiekt, natychmiast wywołaj .toString() lub uzyskaj dostęp do właściwości ciągu.

Before · JavaScript
After · JavaScript
// 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"}
Traktowanie UUID v4 jako sortowalnego

Problem: UUID v4 jest w pełni losowe. Sortowanie po UUID v4 daje losową kolejność, a nie kolejność tworzenia. Prowadzi to do nieprzewidywalnej paginacji, mylących interfejsów administracyjnych i słabej wydajności indeksu bazy danych.

Rozwiązanie: Używaj UUID v7, gdy potrzebujesz czasowo uporządkowanych identyfikatorów. Zachowaj UUID v4 dla tokenów i identyfikatorów korelacji, gdzie kolejność sortowania jest nieistotna.

Before · JavaScript
After · JavaScript
// 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 date
import { 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 time

crypto.randomUUID() vs uuid vs nanoid — szybkie porównanie

Metoda
Format wyjściowy
Wersje UUID
Rozmiar paczki
Typy niestandardowe
Wymaga instalacji
crypto.randomUUID()
36-znakowy UUID v4
tylko v4
0 KB
N/D
Nie (wbudowana)
pakiet uuid npm
36-znakowy UUID
v1, v3, v4, v5, v6, v7
~6,5 KB
N/D
npm install
nanoid
21-znakowy ID URL-safe
Niestandardowy (nie UUID)
~1 KB
N/D
npm install
Ręczna metoda getRandomValues
36-znakowy UUID v4
tylko v4
0 KB
N/D
Nie (wbudowana)
crypto.randomBytes (Node)
Buffer → 36-znakowy UUID v4
tylko v4
0 KB
N/D
Nie (wbudowana Node)
pakiet uuidv7 npm
36-znakowy UUID v7
tylko v7
~2 KB
N/D
npm install

Dla większości projektów JavaScript: używaj crypto.randomUUID() gdy potrzebujesz tylko UUID v4 i Twoje środowisko jest wystarczająco nowe. Sięgnij po pakiet uuid gdy potrzebujesz obsługi v5 (deterministyczne) lub v7 (czasowo uporządkowane). Używaj nanoid gdy krótki, bezpieczny dla URL identyfikator jest bardziej praktyczny niż 36-znakowe UUID — pamiętaj jednak, że wyjście nanoid nie jest zgodne z UUID i nie przejdzie walidacji w żadnym systemie oczekującym formatu RFC 4122.

Jako alternatywę bez kodu wypróbuj Generator UUID v4 do tworzenia identyfikatorów natychmiast w przeglądarce. Aby zbadać istniejący UUID, wklej go do Dekodera UUID by zobaczyć jego wersję, wariant i ewentualne osadzone dane znacznika czasu.

Często zadawane pytania

Jak wygenerować UUID v4 w JavaScript?

Wywołaj crypto.randomUUID() w każdej nowoczesnej przeglądarce (Chrome 92+, Firefox 95+, Safari 15.4+) lub Node.js 19+. Zwraca małoliterowy ciąg, np. "3e7f1a92-4b0c-4d8e-9f12-7a6b3c8d5e1f". W przeglądarkach nie trzeba niczego importować, bo crypto jest globalnym wbudowanym obiektem; w Node.js możesz też użyć import { randomUUID } from "node:crypto", aby jawnie wskazać moduł. Dla środowisk starszych niż Node.js 19 crypto.randomUUID() jest dostępne globalnie — eksperymentalnie od Node.js 14.17.0. Jeśli wolisz opcję bez kodu, generator UUID v4 na /en/uuid/v4 tworzy zgodne identyfikatory jednym kliknięciem.

JavaScript
const sessionId = crypto.randomUUID();
console.log(sessionId);
// "3e7f1a92-4b0c-4d8e-9f12-7a6b3c8d5e1f"

Czy crypto.randomUUID() jest kryptograficznie bezpieczne?

Tak. crypto.randomUUID() używa tego samego CSPRNG (kryptograficznie bezpiecznego generatora liczb pseudolosowych), który zasila crypto.getRandomValues(). 122 losowe bity w UUID v4 sprawiają, że prawdopodobieństwo kolizji jest pomijalnie małe — trzeba by wygenerować około 2,71 kwintyliona UUID, by osiągnąć 50% szansę jednej kolizji. Entropia pochodzi z systemowego źródła losowości (/dev/urandom na Linuksie, BCryptGenRandom na Windows), a nie z Math.random(), które nie jest kryptograficznie bezpieczne. Oznacza to, że wartości UUID v4 są bezpieczne jako tokeny sesji, tokeny CSRF i inne wrażliwe identyfikatory. Nigdy nie zastępuj generatorów UUID opartych na Math.random() w kontekstach bezpieczeństwa.

Czy można używać UUID v4 jako klucza głównego bazy danych?

Można, ale wiąże się to z istotnym kosztem wydajności. UUID v4 jest w pełni losowe, więc indeksy B-drzewa fragmentują się, bo każdy nowy wiersz jest wstawiany w losowym miejscu indeksu zamiast na końcu. W tabelach z dużą liczbą zapisów powoduje to nadmierne podziały stron i chybienia w pamięci podręcznej, co pogarsza wydajność INSERT i skanowania zakresowego. Jeśli baza danych to obsługuje (PostgreSQL, MySQL 8.0+, SQL Server), UUID v7 (czasowo uporządkowane) jest lepszym kluczem głównym, bo nowe wiersze zawsze trafiają na koniec indeksu. UUID v4 pozostaje właściwym wyborem dla tokenów sesji, parametrów stanu OAuth, kluczy idempotentności, identyfikatorów korelacji i pól, w których ukrycie czasu utworzenia jest pożądane.

JavaScript
// UUID v4 — losowe, nie sortowalne
const correlationId = crypto.randomUUID();

// UUID v7 — czasowo uporządkowane, lepsze dla kluczy głównych BD
import { v7 as uuidv7 } from 'uuid';
const rowId = uuidv7();

Jaka jest różnica między UUID v4 a UUID v7?

UUID v4 wypełnia 122 bity losowymi danymi — każdy segment to efektywnie szum. UUID v7 (RFC 9562, opublikowany w 2024 r.) koduje 48-bitowy uniksowy znacznik czasu w milisekundach w pierwszym segmencie, 12 bitów submilisekundowej precyzji w drugim segmencie i losowe bity w pozostałych częściach. Oba mają 128 bitów i korzystają z tego samego 36-znakowego formatu z myślnikami, więc są wymienne na poziomie przechowywania. UUID v7 jest leksykograficznie sortowalny według czasu utworzenia, co utrzymuje kompaktowość indeksów B-drzewa i sprawia, że zapytania zakresowe na oknach czasowych są wydajne. Wybierz UUID v4, gdy identyfikator nie powinien ujawniać czasu utworzenia — na przykład w publicznych tokenach, gdzie informacje o czasie mogłyby być wykorzystane — a UUID v7 dla kluczy głównych bazy danych, dzienników audytu i strumieni zdarzeń, gdzie liczy się kolejność chronologiczna.

Jak sprawdzić poprawność ciągu UUID v4 w JavaScript?

Przetestuj względem wyrażenia regularnego /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i. Literalna "4" na pozycji 15 (indeksowanej od 0) potwierdza nibble wersji; znak na pozycji 20 — jeden z 8, 9, a lub b — koduje bity wariantu RFC 4122. To wyrażenie regularne poprawnie odrzuca UUID v1, v7 i każdy zniekształcony ciąg. Flaga i sprawia, że wielkość liter nie ma znaczenia, więc wielkie cyfry szesnastkowe z innych systemów przechodzą walidację bez normalizacji. Jeśli potrzebujesz tylko sprawdzić, czy ciąg jest dowolnym prawidłowym UUID (niezależnie od wersji), użyj luźniejszego wzorca /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.

JavaScript
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"); // false

Jak wygenerować krótki unikalny identyfikator w JavaScript?

Usuń myślniki z UUID v4, aby otrzymać 32-znakowy ciąg szesnastkowy: crypto.randomUUID().replaceAll("-", ""). Dla jeszcze krótszego wyniku użyj nanoid, który domyślnie generuje 21-znakowy ID URL-safe (A–Z, a–z, 0–9, _ i -) przy porównywalnej odporności na kolizje jak pełny UUID. Kompromis jest prosty: krótsze identyfikatory mają wyższe prawdopodobieństwo kolizji, ale nanoid przy 21 znakach zapewnia 126 bitów entropii, co jest więcej niż wystarczające dla praktycznie każdej aplikacji. Dla slugów URL i ładunków kodu QR można zejść do 10–12 znaków z nanoid, zanim prawdopodobieństwo kolizji stanie się problemem przy typowych częstotliwościach generowania. Unikaj kodowania UUID w Base64 i obcinania go — obcinanie niszczy statystyczną niezależność bitów i utrudnia rozumowanie o kolizjach.

JavaScript
// 32-znakowy ciąg szesnastkowy z UUID v4
const hexId = crypto.randomUUID().replaceAll('-', '');
// "3e7f1a924b0c4d8e9f127a6b3c8d5e1f"

// 21-znakowy ID URL-safe via nanoid
import { nanoid } from 'nanoid';
const shortId = nanoid();
// "V1StGXR8_Z5jdHi6B-myT"

Powiązane narzędzia

Dostępne również w:Python
SL
Sophie LaurentTypeScript & Full-stack Developer

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.

MW
Marcus WebbRecenzent techniczny

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.