ToolDeck

JavaScriptでUUID v4を生成する方法オンライン

·TypeScript & Full-stack Developer·レビュー担当Marcus Webb·公開日

無料の UUID v4ジェネレーター をブラウザで直接使用 — インストール不要。

UUID v4ジェネレーター をオンラインで試す →

JavaScript アプリケーションは必ずユニーク識別子を必要とします — セッショントークン、データベース行、 決済 API の冪等性キー、分散トレーシングの相関 ID など。今日 JavaScript で UUID v4 を生成する最もシンプルな方法は crypto.randomUUID() です: 依存関係ゼロ、1 行、暗号論的に安全。UUID v4 はサービス間の調整が不要なため広く使われています — クライアントとサーバーが衝突リスクなしに独立して ID を生成できます。 このガイドでは、その組み込み API、 uuid npm パッケージ、 バリデーションをすべて Node.js 19+ とモダンブラウザで解説します。コード不要な選択肢として、 ToolDeck の UUID v4 ジェネレーター で即座に準拠した識別子を生成できます。

  • crypto.randomUUID() はブラウザと Node.js に組み込まれています — 依存関係ゼロ、1 行のコードで使えます。
  • 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 パッケージはランダム ID 以上が必要なときに v1、v3、v5、v7 サポートを追加します。
  • データベース主キーには UUID v4(ランダム)より UUID v7(時刻順)を推奨します。インデックスの断片化を減らせます。

UUID v4 とは?

UUID(Universally Unique Identifier)バージョン 4 は、4 つのハイフンで区切られた 32 桁の16進数からなる 128 ビットのランダム識別子です: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx。 15 番目の位置にある 4 はバージョンを示します。 20 番目の位置にある y 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 経由で実験的サポート)で利用可能です。 小文字の 36 文字 UUID v4 文字列を返します。ブラウザ 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 — 2 つの同等なアプローチ
// アプローチ 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"

コードが古いブラウザや組み込み WebView で実行される可能性がある場合、 crypto.randomUUID の機能検出を行うことをお勧めします。チェックは単一の 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() に 依存できない場合があります — crypto API を 削除した WebView を対象にしている場合や、内部動作を理解したい場合などです。手動アプローチでは crypto.getRandomValues() (IE 11 以降で利用可能)を使用して 16 バイトにランダムデータを格納し、 2 つのビットマスク操作でバージョンとバリアントフィールドを設定します。 この 2 つの操作が UUID v4 と純粋なランダムバイト列との唯一の違いです。

JavaScript — getRandomValues を使った手動 UUID v4
function uuidv4Manual() {
  const bytes = new Uint8Array(16);
  crypto.getRandomValues(bytes);

  // バージョンを設定: バイト 6 のビット 12–15 = 0100(バージョン 4)
  bytes[6] = (bytes[6] & 0x0f) | 0x40;

  // バリアントを設定: バイト 8 のビット 6–7 = 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
警告:UUID の生成に Math.random() を絶対に使用しないでください。暗号論的に安全ではなく、 出力の周期が短すぎ、一部のエンジンでは予測可能なシーケンスを生成します。常に crypto.getRandomValues() または crypto.randomUUID() を使用してください。

uuid npm パッケージ — マルチバージョンサポート

npm の uuid パッケージは crypto.randomUUID() が存在する前から JavaScript の定番 UUID ライブラリです。 以下の 3 つの状況では依然として有用です:v4 以外の UUID バージョン(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()、Node.js では crypto.randomBytes() を使用しているため、 エントロピーソースはネイティブ API と同一です。違いは追加のユーティリティ関数と マルチバージョンサポートのみです。

コードをまったく書きたくない場合は、 UUID v4 ジェネレーター をお試しください — ブラウザ上でワンクリックで RFC 4122 準拠の v4 識別子を生成できます。

決定論的 UUID — 文字列から UUID v5 を生成する

UUID v4 は定義上ランダムです — 2 回呼び出すと必ず異なる結果を返します。 逆が必要な場合もあります:同じ入力文字列が常に同じ UUID を生成すべき場合です。 それが UUID v5 です。ネームスペース UUID と入力文字列を SHA-1 でハッシュし、 結果を UUID としてフォーマットします。 同じネームスペース + 同じ入力 = どのマシンでも毎回同じ出力になります。 これは URL、メールアドレス、またはリソースを識別する任意の文字列から安定した ID を導出するのに役立ちます。

JavaScript — 決定論的 ID に uuid v5 を使用
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 は SHA-1 の代わりに MD5 を使用して同じことを行います。新しいプロジェクトでは v5 を推奨します。 MD5 には既知の衝突の弱点がありますが、ID 生成においては大きな問題ではないものの、 両方が利用可能な場合に MD5 を選ぶ理由はありません。

crypto.randomUUID() および関連 API リファレンス

ネイティブの crypto.randomUUID() は引数を取りません — 文字列を返すだけです。依存関係ゼロで RFC 4122 準拠の識別子が必要な場合に使用します。 フォーマット済み UUID 文字列の代わりに生のランダムバイトが必要な場合(例えば型付き配列に格納したり、 鍵を導出したりする場合)は crypto.getRandomValues() を直接使用してください。UUID 作業で重要な関連 API を以下に示します。

プロパティ/メソッド
戻り値の型
説明
crypto.randomUUID()
string
ハイフン付き小文字16進数の36文字 UUID v4 文字列を返す
crypto.getRandomValues(arr)
TypedArray
型付き配列に暗号論的乱数を格納する — 手動 UUID 生成の基盤となるメソッド
URL.createObjectURL(blob)
string
ユニークな Blob URL を生成する(UUID ではないが混同されることがある)

UUID v4 正規表現パターンの内訳:

セグメント
パターン
意味
[0-9a-f]{8}
xxxxxxxx
先頭 8 桁の16進数 — 32 ビットのランダム値
[0-9a-f]{4}
xxxx
次の 4 桁の16進数 — 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 桁の16進数 — 48 ビットのランダム値

正規表現で UUID v4 を検証する

文字列が正しい UUID v4 かどうかの検証は常に必要です — 受信 API リクエストボディ、 URL パラメーター、Webhook ペイロードなど。依存関係ゼロで v4 のみを検証する場合は 手書きの正規表現が適切な選択です。すでに uuid パッケージを使用している場合は、すべての UUID バージョンに対応しカスタムパターンのメンテナンスより エラーが少ない validate() エクスポートを優先してください。正規表現 /^[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() を、 テキストから UUID を抽出するには .match() を使用してください。

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 — バージョンニブルが 4 ではなく 1
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"

ファイルと API レスポンスへの UUID 付与

実際には crypto.randomUUID() を単独で呼び出すことはほとんどありません。よく見られるパターンが 2 つあります: データベースに書き込む前にレコードに ID を割り当てることと、 ログでサービス間のリクエストを追跡できるよう送信 API リクエストに相関 ID を付与することです。

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(`${records.length} 件のレコードに ID を割り当て → ${outputPath}`);
}

assignIds('warehouse-products.ndjson', 'warehouse-products-with-ids.ndjson');
// 1284 件のレコードに ID を割り当て → warehouse-products-with-ids.ndjson

送信 API リクエストへの相関 ID 付与

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} (相関ID: ${correlationId})`);
    return result;
  } catch (err) {
    console.error(`[correlation:${correlationId}] 配送失敗: ${err.message}`);
    throw err;
  }
}

await createShipment({
  order_id: "ord_8a3f91bc",
  destination: { city: "東京", state: "東京都", zip: "100-0001" },
  items: [{ sku: "WH-7291", quantity: 2, weight_kg: 1.4 }],
});

コマンドラインでの UUID 生成

スクリプトは常に必要ではありません。Node.js はコマンドラインから直接 UUID を生成でき、 シェルスクリプト、CI パイプライン、素早いアドホックテストに便利です。 -e フラグは 1 つの式を評価します。

bash — コマンドラインで UUID を生成
# 1 つの UUID
node -e "console.log(crypto.randomUUID())"
# 3e7f1a92-4b0c-4d8e-9f12-7a6b3c8d5e1f

# 5 つの UUID を一度に生成
node -e "for(let i=0;i<5;i++) console.log(crypto.randomUUID())"

# 生成してシェル変数に代入
export REQUEST_ID=$(node -e "process.stdout.write(crypto.randomUUID())")
echo "Request ID: $REQUEST_ID"

# npx uuid を使用(グローバルインストール済みまたは1回限りの場合)
npx uuid v4
# 1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed
bash — ブラウザコンソールで UUID を生成(Node.js 不要)
# 任意のブラウザの DevTools コンソールを開いて入力:
crypto.randomUUID()
# "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"
注意:CI パイプラインで UUID が必要で Node.js が利用できない場合、 uuidgen は macOS と多くの Linux ディストリビューションに プリインストールされています。モダンシステムではデフォルトで UUID v4 を生成します。

高性能な代替手段 — nanoid

1 秒間に何千もの ID を生成する必要があり、36 文字の UUID 形式が必須要件でない場合は、 nanoid を検討してください。 uuid.v4() の 2 倍速く、デフォルトで 21 文字の URL セーフ ID を生成し、ミニファイ後約 1 KB です。 出力は UUID ではなくカスタムアルファベット ID であるため、RFC 4122 準拠が必要な場所 (データベースの UUID カラム、UUID 形式を検証する API、OpenTelemetry トレース ID)では使用しないでください。 ただし内部の相関 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"

// カスタムアルファベット — 16進数のみ、32 文字(ハイフンなし UUID v4 と同等のエントロピー)
const hexId = customAlphabet('0123456789abcdef', 32);
console.log(hexId());
// "4f8a1b2c3d7e9f0a5b6c8d1e2f3a4b5c"

ターミナル出力のシンタックスハイライト

UUID が多用されるアプリケーションのデバッグでは、ターミナルで16進数の文字列を大量に眺めることになります。 色付けが役立ちます。 chalk ライブラリ(または Node.js 21.7+ の新しい組み込み node:util styleText)を使用すると、ログ出力で UUID を周囲のテキストから目立たせることができます。

Node.js — chalk でカラーコードされた UUID 出力
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 を使用してください。

JavaScript で短いユニーク ID を生成する

36 文字の UUID は長すぎる場合があります — URL スラッグ、QR コードデータ、SMS メッセージ、 組み込みハードウェアプロトコルはすべて長さの制約があります。

JavaScript — 短い ID を生成する 3 つの手法
import { randomUUID } from 'node:crypto';

// 1. UUID v4 からハイフンを除去 → 32 文字の16進数文字列
const hex32 = randomUUID().replaceAll('-', '');
console.log(hex32);
// "3e7f1a924b0c4d8e9f127a6b3c8d5e1f"(32 文字)

// 2. 16 バイトのランダム値を Base64 エンコード → 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 秒間に 1,000 個の ID を生成する場合、衝突確率 1% に達するまでに約 116 年かかります。 ほとんどのアプリケーションには十分すぎる値です。1 日に数百万個の ID を生成する場合は、 フル UUID を使用するか、少なくとも 21 文字の nanoid を使用してください。

UUID v7 — v4 の時刻順代替

UUID v7(RFC 9562 で定義)は最初のセグメントに 48 ビットの Unix ミリ秒タイムスタンプを埋め込み、 続いてランダムビットを格納します。結果は v4 に似た UUID ですが時系列にソートされます。 これによりデータベース主キーとして v4 より優れた選択肢となります: 新しい行がランダムな位置ではなく常に B ツリーインデックスの末尾に追加されるため、 ページ分割と断片化が減少します。Postgres テーブルで時刻順 ID が必要なプロジェクトでは、 すぐに v7 に切り替えます — 大規模ではインデックスパフォーマンスの差が顕著です。ToolDeck の UUID v7 ジェネレーター では任意の v7 UUID の埋め込みタイムスタンプを確認できます。

JavaScript — uuid パッケージで UUID v7 を生成
import { v7 as uuidv7 } from 'uuid';

// 3 つの 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 パッケージは バージョン 9.0.0 以降で v7 をサポートします。 古いバージョンを使用している場合は npm install uuid@latest を実行してアップグレードしてください。

ビルドステップなしでブラウザで UUID v4 を使用する

バンドラーも npm も、トランスパイラーも不要です。ただのプレーン HTML ファイルです。 これはクライアントサイド JavaScript で UUID を生成する最もシンプルな方法です。 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>
    // ページ読み込み時に 1 つ生成
    document.getElementById('output').textContent = crypto.randomUUID();
  </script>
</body>
</html>

これがファイルの全体です。CDN インポートも、ライブラリを読み込むスクリプトタグも不要です。 バッチ生成、バリデーション、決定論的 ID など、より複雑なことには uuid パッケージまたは前述の手動フォールバックが必要です。ただし素早いプロトタイプや社内ツールであれば、 これで十分です。

よくあるミス

古いブログ記事からコピーされた Math.random() UUID パターンが本番コードに入り込むのを数え切れないほど見てきました。 これらのパターンが引き起こすバグはサイレントです:ランタイムエラーは発生せず、 負荷時やセキュリティレビューで後になって表面化する微妙な不正動作が起きます。

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);
    }
  );
}
// 安全 — OS の 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() は小文字の16進数を返しますが、他のシステム(データベース、API、ユーザー入力)からの UUID は大文字を使用することがあります。大文字・小文字が異なる場合、直接の === 比較は失敗します。

解決策: 比較前に両方を小文字に正規化してください。

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 でソートすると任意の順序になり、作成順にはなりません。これにより予測不可能なページネーション、混乱する管理画面、悪いデータベースインデックスパフォーマンスが発生します。

解決策: 時刻順の識別子が必要な場合は UUID v7 を使用してください。ソート順序が無関係なトークンと相関 ID には UUID v4 を維持してください。

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 KB
該当なし
不要(組み込み)
uuid npm パッケージ
36文字 UUID
v1, v3, v4, v5, v6, v7
~6.5 KB
該当なし
npm install
nanoid
21文字 URL セーフ ID
カスタム(UUID 非準拠)
~1 KB
該当なし
npm install
手動 getRandomValues
36文字 UUID v4
v4 のみ
0 KB
該当なし
不要(組み込み)
crypto.randomBytes (Node)
Buffer → 36文字 UUID v4
v4 のみ
0 KB
該当なし
不要(Node 組み込み)
uuidv7 npm パッケージ
36文字 UUID v7
v7 のみ
~2 KB
該当なし
npm install

ほとんどの JavaScript プロジェクトでは:ランタイムが十分に新しく UUID v4 のみが必要な場合は crypto.randomUUID() を使用してください。v5(決定論的)または v7(時刻順)サポートが必要な場合は uuid パッケージを使用してください。36 文字の UUID より短く URL セーフな ID が実用的な場合は nanoid を使用してください — ただし nanoid の出力は UUID 準拠ではなく、RFC 4122 形式を期待するシステムでの バリデーションは失敗することを覚えておいてください。

コード不要の代替手段として、 UUID v4 ジェネレーター でブラウザ上で即座に識別子を作成できます。既存の UUID を検査するには、 UUID デコーダー に貼り付けてバージョン、バリアント、および埋め込みタイムスタンプデータを確認してください。

よくある質問

JavaScript で UUID v4 を生成するにはどうすればよいですか?

モダンブラウザ(Chrome 92+、Firefox 95+、Safari 15.4+)または Node.js 19+ で crypto.randomUUID() を呼び出します。"3e7f1a92-4b0c-4d8e-9f12-7a6b3c8d5e1f" のような小文字文字列を返します。ブラウザでは crypto がグローバル組み込みのためインポート不要です。Node.js では import { randomUUID } from "node:crypto" と明示的にインポートすることもできます。Node.js 19 より古いランタイムでも、Node.js 14.17.0 から実験的に crypto.randomUUID() がグローバルで利用可能です。コードを書かずに使いたい場合は、/en/uuid/v4 の UUID v4 ジェネレーターでワンクリックして準拠した識別子を生成できます。

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

crypto.randomUUID() は暗号論的に安全ですか?

はい。crypto.randomUUID() は crypto.getRandomValues() と同じ CSPRNG(暗号論的擬似乱数生成器)を使用します。UUID v4 の 122 ビットのランダム値により、衝突確率は実用上無視できるほど小さく、50% の衝突確率に達するには約 27 億京(2.71 quintillion)個の UUID を生成する必要があります。エントロピーはオペレーティングシステムのランダムソース(Linux の /dev/urandom、Windows の BCryptGenRandom)から得られており、Math.random() は使用されません。Math.random() は暗号論的に安全ではありません。したがって UUID v4 の値は、予測不可能性が求められるセッショントークン、CSRF トークン、その他のセキュリティ上重要な識別子として安全に使用できます。セキュリティコンテキストで Math.random() ベースの UUID ジェネレーターを代用しないでください。

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 — 時刻順、DB 主キーに適している
import { v7 as uuidv7 } from 'uuid';
const rowId = uuidv7();

UUID v4 と UUID v7 の違いは何ですか?

UUID v4 は 122 ビットすべてにランダムデータを格納します。すべてのセグメントは実質的にランダムです。UUID v7(RFC 9562、2024年公開)は最初のセグメントに 48 ビットの Unix ミリ秒タイムスタンプ、2 番目のセグメントに 12 ビットのサブミリ秒精度、残りにランダムビットを格納します。どちらも合計 128 ビットで、同じ 36 文字のハイフン区切り形式を使用するため、ストレージ層では互換性があります。UUID v7 は作成時刻によって辞書順にソートでき、B ツリーインデックスをコンパクトに保ち、時間ウィンドウでの範囲クエリを効率化します。ID が作成時刻を公開してはならない場合(タイミング情報が悪用される可能性がある公開向けトークンなど)は UUID v4 を、データベース主キー・監査ログ・イベントストリームなど時系列順が重要な場合は UUID v7 を選択してください。

JavaScript で UUID v4 文字列を検証するにはどうすればよいですか?

/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i の正規表現でテストします。15 番目の位置(0 インデックス)にあるリテラル "4" がバージョンニブルを確認し、20 番目の位置にある文字(8、9、a、b のいずれか)が RFC 4122 バリアントビットをエンコードしています。この正規表現は UUID v1、v7、および不正な文字列を正しく拒否します。i フラグによって大文字・小文字を区別しないため、他のシステムからの大文字の16進数もノーマライズなしで検証をパスします。バージョンに関係なく有効な 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

JavaScript で短いユニーク ID を生成するにはどうすればよいですか?

UUID v4 からハイフンを取り除くことで 32 文字の16進数文字列を得られます:crypto.randomUUID().replaceAll("-", "")。さらに短くしたい場合は nanoid を使用してください。デフォルトで 21 文字の URL セーフ ID(A–Z、a–z、0–9、_ と -)を生成し、フル UUID と同等の衝突耐性があります。トレードオフは明確です。短い ID は衝突確率が高くなりますが、21 文字の nanoid は 126 ビットのエントロピーを提供し、ほぼすべての実用的なアプリケーションには十分です。URL スラッグや QR コードペイロードでは、典型的な生成レートで衝突確率が懸念される前の最短で 10〜12 文字まで短縮できます。生の UUID を Base64 エンコードして切り捨てることは避けてください。切り捨てによってビットの統計的独立性が損なわれ、衝突の推測が困難になります。

JavaScript
// UUID v4 から 32 文字の16進数文字列を生成
const hexId = crypto.randomUUID().replaceAll('-', '');
// "3e7f1a924b0c4d8e9f127a6b3c8d5e1f"

// nanoid で 21 文字の URL セーフ ID を生成
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.