UUID v4 у JavaScript — crypto.randomUUID()

·TypeScript & Full-stack Developer·ПеревіреноMarcus Webb·Опубліковано

Використовуйте безкоштовний UUID v4 Generator прямо в браузері — без встановлення.

Спробувати UUID v4 Generator онлайн →

Кожному JavaScript-застосунку рано чи пізно потрібні унікальні ідентифікатори — токени сесій, рядки бази даних, ключі ідемпотентності для платіжних API, кореляційні ID для розподіленого трасування. Найпростіший спосіб згенерувати UUID v4 у JavaScript сьогодні — це crypto.randomUUID(): нуль залежностей, один рядок, криптографічно безпечно. UUID v4 широко використовується саме тому, що не потребує координації між сервісами — клієнт і сервер можуть незалежно генерувати ID без ризику колізій. Цей посібник охоплює вбудований API, uuid npm-пакет, валідацію — все для Node.js 19+ і сучасних браузерів. Для варіанту без коду скористайтеся генератором UUID v4 на ToolDeck, який миттєво створює коректні ідентифікатори.

  • crypto.randomUUID() вбудований у браузери та Node.js — нуль залежностей, один рядок коду.
  • UUID v4 — 128-бітний випадковий ідентифікатор: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx (y — це 8, 9, a або b).
  • Перевіряйте за /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i — перевіряє біти версії та варіанту.
  • Пакет uuid npm додає підтримку v1, v3, v5 та v7, коли потрібно більше ніж випадкові ID.
  • Для первинних ключів баз даних надавайте перевагу UUID v7 (впорядкованому за часом) над v4 (випадковим), щоб зменшити фрагментацію індексу.

Що таке UUID v4?

UUID (Universally Unique Identifier) версії 4 — це 128-бітний випадковий ідентифікатор, відформатований як 32 шістнадцяткових цифри, розділені чотирма дефісами: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx. Символ 4 на позиції 15 позначає версію. Символ y на позиції 20 — одне з 8, 9, a або b (варіант RFC 4122). Решта 122 біти є випадковими. UUID v4 — найпоширеніша версія в JavaScript-застосунках, бо не потребує координації між системами — ви можете генерувати ID незалежно на клієнті і сервері без турботи про колізії.

Before · javascript
After · javascript
// Без ідентифікатора
const event = { action: "user.login", ts: 1711824000 };
// З UUID v4
const event = {
  id: "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
  action: "user.login",
  ts: 1711824000
};

crypto.randomUUID() — Нативний підхід у JavaScript

crypto.randomUUID() доступний у Chrome 92+, Firefox 95+, Safari 15.4+ та Node.js 19+ (з експериментальною підтримкою з Node.js 14.17.0 через globalThis.crypto). Повертає рядок UUID v4 з 36 символів у нижньому регістрі. У браузерному JavaScript імпорт не потрібен. У Node.js можна викликати його безпосередньо на глобальному об'єкті cryptoабо явно імпортувати з модуля node:crypto.

JavaScript — браузер (нуль імпортів)
// Працює в будь-якому сучасному браузері — без збірки, без бандлера
const requestId = crypto.randomUUID();
console.log(requestId);
// "3e7f1a92-4b0c-4d8e-9f12-7a6b3c8d5e1f"

// Використовуйте там, де потрібен унікальний ідентифікатор
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 — два рівнозначних підходи
// Підхід 1: глобальний crypto (Node.js 19+)
const orderId = crypto.randomUUID();
console.log(orderId);
// "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"

// Підхід 2: явний імпорт з node:crypto
import { randomUUID } from 'node:crypto';
const correlationId = randomUUID();
console.log(correlationId);
// "f7e6d5c4-b3a2-4190-8f7e-6d5c4b3a2190"

Виявлення підтримки crypto.randomUUID варто робити, якщо ваш код може виконуватися в старших браузерах або вбудованих WebView. Перевірка — це один оператор typeof:

JavaScript — виявлення підтримки з резервним варіантом
function generateUUIDv4() {
  // Надаємо перевагу нативному API, якщо він доступний
  if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
    return crypto.randomUUID();
  }

  // Ручний резервний варіант через getRandomValues (див. наступний розділ)
  const bytes = new Uint8Array(16);
  crypto.getRandomValues(bytes);

  // Встановлюємо версію (4) та варіант (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"
Примітка:У безпечних контекстах (HTTPS-сторінки, localhost, розширення браузера) crypto.randomUUID() завжди доступний. У деяких браузерах він викидає виняток на незахищених HTTP-сторінках. Якщо ваш застосунок може запускатися на звичайному HTTP під час розробки, наведений вище резервний варіант на getRandomValues вирішує цю проблему.

Генерація UUID v4 без бібліотеки

Іноді не можна покладатися на crypto.randomUUID() — можливо, ви орієнтуєтеся на WebView, який обрізає crypto API, або хочете зрозуміти, що відбувається під капотом. Ручний підхід використовує crypto.getRandomValues() (доступний з IE 11) для заповнення 16 байт випадковими даними, а потім застосовує дві операції побітового маскування для встановлення полів версії та варіанту. Ці дві операції — єдина різниця між UUID v4 та чистим рядком випадкових байтів.

JavaScript — ручний UUID v4 з getRandomValues
function uuidv4Manual() {
  const bytes = new Uint8Array(16);
  crypto.getRandomValues(bytes);

  // Встановлюємо версію: біти 12–15 байту 6 = 0100 (version 4)
  bytes[6] = (bytes[6] & 0x0f) | 0x40;

  // Встановлюємо варіант: біти 6–7 байту 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"

// Перевіряємо, що він проходить валідацію 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
Попередження:Ніколи не використовуйте Math.random() для генерації UUID. Він не є криптографічно безпечним, його вихідний період занадто короткий, а деякі рушії генерують передбачувані послідовності. Завжди використовуйте crypto.getRandomValues() або crypto.randomUUID().

Пакет uuid npm — підтримка кількох версій

Пакет uuid на npm був основною UUID-бібліотекою для JavaScript ще до появи crypto.randomUUID(). Він все ще має сенс у трьох ситуаціях: вам потрібні версії UUID, відмінні від v4 (v1, v3, v5, v7), ви орієнтуєтеся на середовища старші за Node.js 14.17.0, або вам потрібні утилітарні функції validate та parse. Для звичайного UUID v4 на сучасному середовищі нативного API достатньо, і я б уникав цієї залежності.

bash — встановлення
npm install uuid
JavaScript — пакет uuid для генерації v4
import { v4 as uuidv4, validate, version } from 'uuid';

// Генеруємо UUID v4
const paymentId = uuidv4();
console.log(paymentId);
// "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed"

// Перевіряємо будь-який рядок UUID
console.log(validate(paymentId));    // true
console.log(validate("not-a-uuid")); // false

// Визначаємо версію UUID
console.log(version(paymentId));     // 4

// Генеруємо пакет для наповнення тестової бази даних
const testAccounts = Array.from({ length: 5 }, () => ({
  account_id: uuidv4(),
  plan: "starter",
  created_at: new Date().toISOString(),
}));
console.log(testAccounts);
Примітка:Пакет uuid внутрішньо використовує crypto.getRandomValues() у браузерах та crypto.randomBytes() у Node.js, тому джерело ентропії ідентичне нативному API. Різниця полягає лише в додаткових утилітарних функціях та підтримці кількох версій.

Якщо ви взагалі не хочете писати код, спробуйте генератор UUID v4 — він генерує ідентифікатори v4 відповідно до RFC 4122 безпосередньо у браузері одним кліком.

Детерміновані UUID — Генерація UUID v5 з рядка

UUID v4 є випадковим за визначенням — два виклики завжди дають різні результати. Іноді потрібне протилежне: однаковий вхідний рядок повинен завжди давати однаковий UUID. Саме це робить UUID v5. Він хешує простір імен UUID та вхідний рядок за допомогою SHA-1, а потім форматує результат як UUID. Однакові простір імен + однаковий вхід = однаковий вивід, завжди, на будь-якій машині. Це корисно для виведення стабільних ID з URL, електронних адрес або будь-якого рядка, який вже ідентифікує ресурс.

JavaScript — uuid v5 для детермінованих ID
import { v5 as uuidv5 } from 'uuid';

// Вбудований простір імен для URL (RFC 4122)
const URL_NAMESPACE = uuidv5.URL;
// "6ba7b811-9dad-11d1-80b4-00c04fd430c8"

// Однаковий URL завжди дає однаковий 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"

// Власний простір імен для вашого застосунку
const APP_NAMESPACE = "f47ac10b-58cc-4372-a567-0e02b2c3d479";
const tenantId = uuidv5("acme-corp", APP_NAMESPACE);
console.log(tenantId);
// "d4735e3a-265b-564e-8f32-7a1b2c3d4e5f"

Коротка нотатка: UUID v3 робить те саме, але з MD5 замість SHA-1. Надавайте перевагу v5 для нових проєктів. MD5 має відомі вразливості до колізій, і хоча це не має великого значення для генерації ID, немає причин обирати його замість SHA-1, коли обидва доступні.

Довідник crypto.randomUUID() та пов'язаних API

Нативний crypto.randomUUID() не приймає жодних аргументів — він повертає рядок і нічого більше. Використовуйте його, коли потрібні ідентифікатори, сумісні з RFC 4122, без залежностей. Коли замість відформатованого рядка UUID потрібні необроблені випадкові байти — наприклад, для заповнення типізованого масиву або виведення ключа — використовуйте crypto.getRandomValues() безпосередньо. Пов'язані API, важливі для роботи з UUID, перераховані нижче.

Властивість / Метод
Тип повернення
Опис
crypto.randomUUID()
string
Повертає 36-символьний рядок UUID v4 у нижньому регістрі шістнадцяткових символів з дефісами
crypto.getRandomValues(arr)
TypedArray
Заповнює типізований масив криптографічно випадковими значеннями — основний блок для ручної генерації UUID
URL.createObjectURL(blob)
string
Генерує унікальну URL-адресу blob (не UUID, але іноді з ним плутають)

Розбір регулярного виразу UUID v4:

Сегмент
Шаблон
Значення
[0-9a-f]{8}
xxxxxxxx
Перші 8 шістнадцяткових цифр — 32 випадкових біти
[0-9a-f]{4}
xxxx
Наступні 4 шістнадцяткових цифри — 16 випадкових бітів
4[0-9a-f]{3}
4xxx
Ніббл версії фіксований як 4, далі 12 випадкових бітів
[89ab][0-9a-f]{3}
yxxx
Ніббл варіанту — одне з 8, 9, a, b — далі 12 випадкових бітів
[0-9a-f]{12}
xxxxxxxxxxxx
Останні 12 шістнадцяткових цифр — 48 випадкових бітів

Валідація UUID v4 за допомогою регулярного виразу

Перевірка того, що рядок є правильним UUID v4, виникає постійно — тіла вхідних API-запитів, URL-параметри, вебхук-навантаження. Власний регулярний вираз — правильний вибір, коли вам потрібно нуль залежностей і ви перевіряєте лише v4. Якщо ви вже використовуєте пакет uuid, надавайте перевагу його експорту validate() — він обробляє всі версії UUID і менш схильний до помилок, ніж підтримка власного шаблону. Регулярний вираз /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i перевіряє і ніббл версії (має бути 4), і ніббл варіанту (має бути 8, 9, a або b). Використовуйте RegExp.prototype.test() для булевих перевірок та .match() коли потрібно витягти UUID з навколишнього тексту.

JavaScript — допоміжна функція валідації 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);
}

// Дійсний UUID v4
console.log(isUUIDv4("9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d")); // true

// UUID v1 — ніббл версії 1, а не 4
console.log(isUUIDv4("550e8400-e29b-11d4-a716-446655440000")); // false

// UUID v7 — ніббл версії 7
console.log(isUUIDv4("018e4a0c-5b3f-7d12-8a9b-0c1d2e3f4a5b")); // false

// Некоректні рядки
console.log(isUUIDv4("not-a-uuid"));           // false
console.log(isUUIDv4(""));                      // false
console.log(isUUIDv4("9b1deb4d3b7d4bad9bdd2b0d7b3dcb6d")); // false (без дефісів)

// Витягуємо UUID з більшого рядка
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"

Генерація та прикріплення UUID з файлу та відповіді API

На практиці crypto.randomUUID() рідко викликають ізольовано. Два шаблони зустрічаються постійно: призначення ID записам перед їх записом до бази даних та прикріплення кореляційних ID до вихідних API-запитів, щоб відстежувати запит між сервісами у журналах.

Читання файлу NDJSON → Призначення UUID → Запис назад

Node.js — призначення UUID записам з файлу
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(`Пропускаємо некоректний рядок: ${err.message}`);
      return null;
    }
  }).filter(Boolean);

  writeFileSync(outputPath, records.join('\n') + '\n');
  console.log(`Призначено ID для ${records.length} записів → ${outputPath}`);
}

assignIds('warehouse-products.ndjson', 'warehouse-products-with-ids.ndjson');
// Призначено ID для 1284 записів → warehouse-products-with-ids.ndjson

Прикріплення кореляційного ID до вихідного API-запиту

Node.js — кореляційний ID для розподіленого трасування
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(`Відправлення створено: ${result.shipment_id} (кореляція: ${correlationId})`);
    return result;
  } catch (err) {
    console.error(`[correlation:${correlationId}] Помилка відправлення: ${err.message}`);
    throw err;
  }
}

await createShipment({
  order_id: "ord_8a3f91bc",
  destination: { city: "Київ", state: "Київська область", zip: "01001" },
  items: [{ sku: "WH-7291", quantity: 2, weight_kg: 1.4 }],
});

Генерація UUID через командний рядок

Скрипт не завжди потрібен. Node.js може генерувати UUID безпосередньо з командного рядка, що зручно для shell-скриптів, CI-пайплайнів та швидкого тестування. Прапор -e обчислює один вираз.

bash — генерація UUID з командного рядка
# Один UUID
node -e "console.log(crypto.randomUUID())"
# 3e7f1a92-4b0c-4d8e-9f12-7a6b3c8d5e1f

# П'ять UUID одразу
node -e "for(let i=0;i<5;i++) console.log(crypto.randomUUID())"

# Генерація та присвоєння змінній shell
export REQUEST_ID=$(node -e "process.stdout.write(crypto.randomUUID())")
echo "Request ID: $REQUEST_ID"

# Використання npx uuid (якщо пакет встановлено глобально або для разового використання)
npx uuid v4
# 1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed
bash — генерація UUID в консолі браузера (без Node.js)
# Відкрийте DevTools будь-якого браузера та введіть:
crypto.randomUUID()
# "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"
Примітка:Якщо вам потрібні UUID в CI-пайплайні і Node.js недоступний, uuidgen попередньо встановлений у macOS та більшості дистрибутивів Linux. На сучасних системах він за замовчуванням генерує UUID v4.

Високопродуктивна альтернатива — nanoid

Якщо ви генеруєте тисячі ID за секунду і 36-символьний формат UUID не є обов'язковою вимогою, розгляньте nanoid. Він у 2 рази швидший за uuid.v4(), за замовчуванням генерує 21-символьний URL-безпечний ID та важить близько 1 КБ після мінімізації. Вивід не є UUID — це ID власного алфавіту — тому не використовуйте його там, де потрібна сумісність з RFC 4122 (стовпці UUID у базі даних, API, що перевіряють формат UUID, ідентифікатори трасування OpenTelemetry). Але для внутрішніх кореляційних ID, ключів React-компонентів та URL-слагів — гарний варіант.

bash — встановлення nanoid
npm install nanoid
JavaScript — nanoid для коротких унікальних ID
import { nanoid, customAlphabet } from 'nanoid';

// За замовчуванням: 21-символьний URL-безпечний ID (A-Za-z0-9_-)
const trackingCode = nanoid();
console.log(trackingCode);
// "V1StGXR8_Z5jdHi6B-myT"

// Власна довжина
const shortCode = nanoid(10);
console.log(shortCode);
// "IRFa-VaY2b"

// Власний алфавіт — тільки цифри, 12 знаків
const numericId = customAlphabet('0123456789', 12);
console.log(numericId());
// "839274651023"

// Власний алфавіт — тільки hex, 32 символи (та сама ентропія, що й UUID v4 без дефісів)
const hexId = customAlphabet('0123456789abcdef', 32);
console.log(hexId());
// "4f8a1b2c3d7e9f0a5b6c8d1e2f3a4b5c"

Виведення у термінал з підсвічуванням синтаксису

Налагодження застосунків з великою кількістю UUID означає розглядати стіни шістнадцяткових рядків у терміналі. Кольорове кодування допомагає. Бібліотека chalk (або новіший вбудований node:util styleText у Node.js 21.7+) дозволяє виділяти UUID у виводі журналу, щоб вони виділялися серед навколишнього тексту.

Node.js — кольоровий вивід UUID за допомогою 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",...}
Попередження:Керуючі послідовності кольорів псують лог-файли та ламають парсери JSON. Використовуйте chalk або styleText лише для виводу в термінал, який людина читає безпосередньо. Для структурованих журналів, що йдуть у файл або агрегатор логів, використовуйте звичайний JSON.

Генерація коротких унікальних ID у JavaScript

36-символьний UUID іноді занадто довгий — URL-слаги, дані QR-кодів, SMS-повідомлення та вбудовані апаратні протоколи мають обмеження на довжину.

JavaScript — три способи отримати коротші ID
import { randomUUID } from 'node:crypto';

// 1. Прибираємо дефіси з UUID v4 → 32-символьний hex-рядок
const hex32 = randomUUID().replaceAll('-', '');
console.log(hex32);
// "3e7f1a924b0c4d8e9f127a6b3c8d5e1f" (32 символи)

// 2. Base64-кодуємо 16 випадкових байтів → 22-символьний рядок (URL-безпечний)
const bytes = new Uint8Array(16);
crypto.getRandomValues(bytes);
const base64Id = Buffer.from(bytes)
  .toString('base64url')
  .replace(/=+$/, '');
console.log(base64Id);
// "Pj8akksNTY6fEnarPIvR" (22 символи, 128 бітів ентропії)

// 3. nanoid з власною довжиною
import { nanoid } from 'nanoid';
const short12 = nanoid(12);
console.log(short12);
// "V1StGXR8_Z5j" (12 символів, ~71 біт ентропії)

Математика ймовірності колізій: 12-символьний nanoid (алфавіт за замовчуванням з 64 символів) дає приблизно 71 біт ентропії. При 1 000 ID за секунду знадобиться близько 116 років, щоб досягти 1% ймовірності колізії. Для більшості застосунків цього більш ніж достатньо. Якщо ви генеруєте мільйони ID на день, використовуйте повний UUID або nanoid щонайменше з 21 символом.

UUID v7 — Впорядкована за часом альтернатива v4

UUID v7 (визначений у RFC 9562) вбудовує 48-бітну мітку часу Unix у мілісекундах у перший сегмент, за якою йдуть випадкові біти. Результат — UUID, схожий на v4, але що сортується хронологічно. Це робить його кращим вибором, ніж v4, для первинних ключів бази даних: нові рядки завжди потрапляють у кінець індексу B-дерева, а не у випадкові позиції, що зменшує розщеплення сторінок та фрагментацію. У проєктах, де мені потрібні впорядковані за часом ID для таблиці Postgres, я одразу переходжу на v7 — різниця у продуктивності індексу помітна при масштабуванні. Генератор UUID v7 на ToolDeck показує вбудовану мітку часу для будь-якого UUID v7.

JavaScript — UUID v7 з пакетом uuid
import { v7 as uuidv7 } from 'uuid';

// Генеруємо три значення UUID v7 — вони сортуються хронологічно
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"

// Вони сортуються лексикографічно за часом створення
console.log([id3, id1, id2].sort());
// [id1, id2, id3] — хронологічний порядок збережено

// Використовуйте v4 для токенів, де не потрібно розкривати час
import { v4 as uuidv4 } from 'uuid';
const sessionToken = uuidv4(); // повністю випадковий, без інформації про час
Примітка:Пакет uuid підтримує v7 починаючи з версії 9.0.0. Якщо у вас стара версія, запустіть npm install uuid@latest, щоб оновитися.

UUID v4 у браузері без кроку збірки

Без бандлера, без npm, без транспілятора. Просто звичайний HTML-файл. Це найпростіший можливий спосіб згенерувати UUID у клієнтському JavaScript. Він працює, бо crypto.randomUUID() — вбудований API браузера.

HTML — мінімальний генератор UUID у браузері
<!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>
    // Генеруємо один UUID при завантаженні сторінки
    document.getElementById('output').textContent = crypto.randomUUID();
  </script>
</body>
</html>

Це весь файл. Жодних CDN-імпортів, жодних тегів script для підтягування бібліотек. Для чогось складнішого — пакетної генерації, валідації, детермінованих ID — вам знадобиться пакет uuid або ручний резервний варіант, показаний раніше. Але для швидкого прототипу або внутрішнього інструменту цього достатньо.

Типові помилки

Я бачив шаблон UUID на Math.random() скопійованим зі старих публікацій у блогах у виробничий код частіше, ніж хотілося б визнавати. Помилки, які вносять ці шаблони, є тихими: жодної помилки виконання, лише непомітно неправильна поведінка, що проявляється пізніше під навантаженням або під час перевірок безпеки.

Використання Math.random() для генерації UUID

Проблема: Math.random() не є криптографічно безпечним. Його вивід передбачуваний у деяких рушіях, а низька ентропія робить колізії набагато ймовірнішими, ніж при використанні справжнього CSPRNG.

Вирішення: Завжди використовуйте crypto.randomUUID() або crypto.getRandomValues(). Обидва використовують CSPRNG операційної системи.

Before · JavaScript
After · JavaScript
// НЕБЕЗПЕЧНО — передбачуваний, низька ентропія
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);
    }
  );
}
// БЕЗПЕЧНО — використовує CSPRNG ОС
const id = crypto.randomUUID();

// Або якщо потрібен ручний резервний варіант:
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('')}`;
}
Порівняння UUID з урахуванням регістру

Проблема: crypto.randomUUID() повертає шістнадцяткові символи у нижньому регістрі, але UUID з інших систем (баз даних, API, введення користувача) можуть використовувати верхній регістр. Пряме порівняння === не спрацьовує при розбіжності регістрів.

Вирішення: Нормалізуйте обидві сторони до нижнього регістру перед порівнянням.

Before · JavaScript
After · JavaScript
const fromApi = "9B1DEB4D-3B7D-4BAD-9BDD-2B0D7B3DCB6D"; // верхній регістр з API
const local  = "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d";  // нижній регістр з crypto

if (fromApi === local) { /* ніколи не виконається */ }
const fromApi = "9B1DEB4D-3B7D-4BAD-9BDD-2B0D7B3DCB6D";
const local  = "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d";

if (fromApi.toLowerCase() === local.toLowerCase()) {
  // збігається правильно
}
Зберігання UUID як об'єктів замість рядків

Проблема: Деякі UUID-бібліотеки (особливо в інших мовах) повертають об'єкти UUID. У JavaScript випадкове обгортання рядка UUID в об'єкт ламає перевірки рівності, серіалізацію JSON та запити до бази даних.

Вирішення: Завжди зберігайте та передавайте UUID як прості рядки. Якщо бібліотека повертає об'єкт, негайно викличте .toString() або отримайте доступ до рядкової властивості.

Before · JavaScript
After · JavaScript
// Створюємо непотрібну обгортку
class UUID {
  constructor(value) { this.value = value; }
}
const id = new UUID(crypto.randomUUID());
console.log(id === id); // true, але...
console.log(JSON.stringify({ id })); // {"id":{"value":"..."}}
// Просто використовуємо рядок
const id = crypto.randomUUID();
console.log(JSON.stringify({ id }));
// {"id":"3e7f1a92-4b0c-4d8e-9f12-7a6b3c8d5e1f"}
Сортування UUID v4 як впорядкованих ідентифікаторів

Проблема: UUID v4 є повністю випадковим. Сортування за UUID v4 дає довільний порядок, а не порядок створення. Це призводить до непередбачуваної пагінації, незрозумілого адміністративного UI та поганої продуктивності індексу бази даних.

Вирішення: Використовуйте UUID v7, коли потрібні впорядковані за часом ідентифікатори. Залишайте UUID v4 для токенів та кореляційних ID, де порядок сортування не важливий.

Before · JavaScript
After · JavaScript
// Погано: використовуємо v4 як сортований первинний ключ
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));
// Порядок сортування є випадковим — НЕ за датою створення
import { v7 as uuidv7 } from 'uuid';
// Добре: v7 сортується за часом створення
const rows = [
  { id: uuidv7(), created: "2026-03-27" },
  { id: uuidv7(), created: "2026-03-26" },
];
rows.sort((a, b) => a.id.localeCompare(b.id));
// Порядок сортування відповідає часу створення

crypto.randomUUID() vs uuid vs nanoid — Швидке порівняння

Метод
Формат виводу
Версії UUID
Розмір бандлу
Власні типи
Потребує встановлення
crypto.randomUUID()
36-символьний UUID v4
тільки v4
0 КБ
Н/Д
Ні (вбудовано)
пакет uuid npm
36-символьний UUID
v1, v3, v4, v5, v6, v7
~6,5 КБ
Н/Д
npm install
nanoid
21-символьний URL-безпечний ID
Власний (не UUID)
~1 КБ
Н/Д
npm install
Ручний getRandomValues
36-символьний UUID v4
тільки v4
0 КБ
Н/Д
Ні (вбудовано)
crypto.randomBytes (Node)
Buffer → 36-символьний UUID v4
тільки v4
0 КБ
Н/Д
Ні (вбудовано в Node)
пакет uuidv7 npm
36-символьний UUID v7
тільки v7
~2 КБ
Н/Д
npm install

Для більшості JavaScript-проєктів: використовуйте crypto.randomUUID() коли вам потрібен лише UUID v4 і ваше середовище виконання досить сучасне. Беріть пакет uuid коли потрібна підтримка v5 (детермінований) або v7 (впорядкований за часом). Використовуйте nanoid коли короткий URL-безпечний ID практичніший, ніж 36-символьний UUID — але пам'ятайте, що вивід nanoid не відповідає UUID і не пройде валідацію в будь-якій системі, яка очікує формат RFC 4122.

Для варіанту без коду спробуйте генератор UUID v4 для миттєвого створення ідентифікаторів у браузері. Щоб перевірити існуючий UUID, вставте його в UUID Decoder щоб побачити його версію, варіант та будь-які вбудовані дані мітки часу.

Часті запитання

Як згенерувати UUID v4 у JavaScript?

Викличте crypto.randomUUID() у будь-якому сучасному браузері (Chrome 92+, Firefox 95+, Safari 15.4+) або Node.js 19+. Метод повертає рядок у нижньому регістрі на кшталт "3e7f1a92-4b0c-4d8e-9f12-7a6b3c8d5e1f". У браузері не потрібен жодний імпорт, оскільки crypto — вбудований глобальний об'єкт; у Node.js також можна скористатися import { randomUUID } from "node:crypto", щоб явно вказати модуль. Для середовищ старших за Node.js 19 crypto.randomUUID() все одно доступний глобально — він був доступний у експериментальному режимі з Node.js 14.17.0. Якщо вам потрібен варіант без коду, генератор UUID v4 на /en/uuid/v4 одразу створює коректні ідентифікатори.

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

Чи є crypto.randomUUID() криптографічно безпечним?

Так. crypto.randomUUID() використовує той самий CSPRNG (криптографічно стійкий псевдовипадковий генератор), що й crypto.getRandomValues(). 122 випадкових біти в UUID v4 роблять імовірність колізії нехтовно малою для будь-яких практичних потреб — потрібно згенерувати приблизно 2,71 квінтильйона UUID, щоб досягти 50% ймовірності навіть однієї колізії. Ентропія надходить з джерела випадковості операційної системи (/dev/urandom у Linux, BCryptGenRandom у Windows), а не з Math.random(), який явно не є криптографічно безпечним. Це означає, що значення UUID v4 безпечно використовувати як токени сесій, CSRF-токени та інші чутливі до безпеки ідентифікатори, де необхідно уникати передбачуваності. Ніколи не замінюйте генератори UUID на основі Math.random() у контекстах безпеки.

Чи можна використовувати UUID v4 як первинний ключ бази даних?

Можна, але є суттєвий компроміс продуктивності. UUID v4 є повністю випадковим, тому індекси B-дерева фрагментуються, бо кожен новий рядок вставляється у випадкову позицію індексу, а не в кінець. На таблицях з інтенсивним записом це спричиняє надмірне розщеплення сторінок та промахи кешу, що погіршує продуктивність INSERT і сканування діапазонів. Якщо ваша база даних підтримує це (PostgreSQL, MySQL 8.0+, SQL Server), UUID v7 (упорядкований за часом) є кращим первинним ключем, оскільки нові рядки завжди додаються в кінець індексу. UUID v4 залишається правильним вибором для токенів сесій, параметрів стану OAuth, ключів ідемпотентності, кореляційних ID та будь-якого поля, де бажано приховати час створення.

JavaScript
// UUID v4 — випадковий, не сортується
const correlationId = crypto.randomUUID();

// UUID v7 — упорядкований за часом, кращий для первинних ключів БД
import { v7 as uuidv7 } from 'uuid';
const rowId = uuidv7();

У чому різниця між UUID v4 та UUID v7?

UUID v4 заповнює 122 біти випадковими даними — кожен сегмент є фактично шумом. UUID v7 (RFC 9562, опублікований у 2024 році) кодує 48-бітну мітку часу Unix в мілісекундах у першому сегменті, 12 бітів субмілісекундної точності у другому сегменті та випадкові біти в решті. Обидва мають 128 бітів і використовують однаковий 36-символьний формат з дефісами, тому вони взаємозамінні на рівні зберігання. UUID v7 лексикографічно сортується за часом створення, що зберігає компактність індексів B-дерева і робить запити за діапазоном часу ефективними. Обирайте UUID v4, коли ID не повинен розкривати час свого створення — наприклад, публічні токени, де інформація про час може бути використана зловмисно — і UUID v7 для первинних ключів баз даних, журналів аудиту та потоків подій, де важливий хронологічний порядок.

Як перевірити рядок UUID v4 у JavaScript?

Перевіряйте за регулярним виразом /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i. Літера "4" на позиції 15 (з індексом 0) підтверджує ніббл версії; символ на позиції 20 — одне з 8, 9, a або b — кодує біти варіанту RFC 4122. Цей регулярний вираз правильно відхиляє UUID v1, v7 та будь-який некоректний рядок. Прапор i робить його нечутливим до регістру, тому великі шістнадцяткові цифри з інших систем проходять перевірку без нормалізації. Якщо вам потрібно лише знати, чи є рядок будь-яким дійсним UUID (незалежно від версії), використовуйте більш загальний шаблон /^[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

Як згенерувати короткий унікальний ID у JavaScript?

Видаліть дефіси з UUID v4, щоб отримати 32-символьний шістнадцятковий рядок: crypto.randomUUID().replaceAll("-", ""). Для ще коротшого варіанту використовуйте nanoid, який за замовчуванням створює 21-символьний URL-безпечний ID (A–Z, a–z, 0–9, _ та -) з порівнянною стійкістю до колізій. Компроміс простий: коротші ID мають вищу ймовірність колізії, але nanoid з 21 символом все одно забезпечує 126 бітів ентропії, чого більш ніж достатньо для практично будь-якого реального застосунку. Для URL-слагів та даних QR-кодів можна опуститися до 10–12 символів з nanoid, перш ніж ймовірність колізії стане проблемою за типових темпів генерації. Уникайте кодування UUID у Base64 та його обрізання — обрізання руйнує статистичну незалежність бітів і ускладнює аналіз колізій.

JavaScript
// 32-символьний шістнадцятковий рядок з UUID v4
const hexId = crypto.randomUUID().replaceAll('-', '');
// "3e7f1a924b0c4d8e9f127a6b3c8d5e1f"

// 21-символьний URL-безпечний ID через nanoid
import { nanoid } from 'nanoid';
const shortId = nanoid();
// "V1StGXR8_Z5jdHi6B-myT"

Пов'язані інструменти

Також доступно на: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 WebbТехнічний рецензент

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.