Skip to content

UUID Generator — JavaScript source

Generate RFC 4122 v4 UUIDs with crypto-grade randomness. Bulk generate, copy all, toggle format (uppercase / no hyphens).

This is the JavaScript implementation — the same logic the interactive tool runs, in a shareable, citable form.

/**
 * RFC 4122 v4 UUID generator (cryptographically secure).
 *
 * Language: JavaScript (ES module, Web Crypto API)
 * CosmoDev polyglot showcase port of the `uuid` tool.
 * Ported from src/lib/uuid.ts - display source, part of CosmoDev's
 * polyglot tool pages.
 *
 * Produces a random (v4) UUID: 36 characters, lowercase, hyphenated as
 * 8-4-4-4-12 hex digits, with the RFC version (4) and variant (10xx)
 * bits set. Backed by the platform CSPRNG, so the result is suitable for
 * any non-reproducible identifier - session IDs, tokens, collision-free
 * primary keys, and the like.
 *
 * This mirrors the live lib exactly: the fast path delegates to
 * crypto.randomUUID() (the platform's own RFC 4122 implementation), and
 * the portable path below is the explicit equivalent every other language
 * in this polyglot set implements.
 */

// Web Crypto CSPRNG - the only secure choice for identifiers that must be
// unpredictable. Never Math.random() (a PRNG, predictable in practice).
const CRYPTO = typeof crypto !== 'undefined' ? crypto : undefined;

/**
 * Generate one RFC 4122 version-4 UUID string.
 *
 * @returns {string} Lowercase 36-char UUID, e.g.
 *                   "f47ac10b-58cc-4372-a567-0e02b2c3d479"
 * @throws {Error} If the Web Crypto API is unavailable (no CSPRNG).
 */
export function uuidv4() {
  if (!CRYPTO) {
    // Equivalent to the lib's implicit failure when no `crypto` is present.
    throw new Error('uuidv4 requires the Web Crypto API');
  }

  // Fast path: the platform already implements RFC 4122 v4 correctly.
  if (typeof CRYPTO.randomUUID === 'function') {
    return CRYPTO.randomUUID();
  }

  // Portable path: 16 random bytes, then stamp the version/variant bits.
  const b = new Uint8Array(16);
  CRYPTO.getRandomValues(b);

  // Byte 6 high nibble -> 0100 (version 4).
  b[6] = (b[6] & 0x0f) | 0x40;
  // Byte 8 high bits   -> 10   (RFC 4122 variant); next hex digit is 8-b.
  b[8] = (b[8] & 0x3f) | 0x80;

  // Render as canonical lowercase 8-4-4-4-12 hex.
  const h = [...b].map((x) => x.toString(16).padStart(2, '0')).join('');
  return `${h.slice(0, 8)}-${h.slice(8, 12)}-${h.slice(12, 16)}-${h.slice(16, 20)}-${h.slice(20)}`;
}

Also available in 13 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →