Skip to content
snip tools

How to generate a UUID in JavaScript

A snip.tools guide · runs alongside the UUID generator

Prefer to just run it? Use the free UUID generator — no install, in your browser.

Open the UUID generator

A UUID (Universally Unique Identifier, also called a GUID) is a 128-bit value you can generate anywhere — on the server, in the browser, on thousands of machines at once — with effectively no chance of two ever colliding. In JavaScript you almost never need a library for this anymore. Here's the modern one-liner, a fallback for old environments, and an explanation of what's actually happening so you can use it with confidence. (This is the exact approach behind our in-browser UUID generator.)

The one-liner: crypto.randomUUID()

The Web Crypto API exposes crypto.randomUUID(), which returns a fresh, cryptographically-random version-4 UUID as a string. It's built in — no npm install, no dependency:

// Modern browsers, Node 16+, Deno, Bun, Cloudflare Workers
const id = crypto.randomUUID();
// → "f47ac10b-58cc-4372-a567-0e02b2c3d479"

It's available in every modern browser, and in Node 16+, Deno, Bun and Cloudflare Workers. One small gotcha in the browser: Web Crypto requires a secure context, so crypto.randomUUID is defined on https:// and on localhost, but not on a plain http:// page. In practice that only matters during local testing over an insecure origin.

Generating several at once

There's no batch API — you just call it in a loop. For a list of n UUIDs:

function uuids(n) {
  return Array.from({ length: n }, () => crypto.randomUUID());
}

uuids(3);
// → [
//     "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed",
//     "5f8e1a0c-2d3b-4e6f-8a90-1c2d3e4f5a6b",
//     "9c8b7a65-4321-4def-8abc-de0123456789"
//   ]

A fallback for old environments

If you must support an environment without crypto.randomUUID (a very old browser, or a polyfill target), you can build a valid v4 UUID yourself from 16 random bytes. The key is that v4 UUIDs aren't fully random: six bits are reserved to mark the version and variant, so a couple of bytes need specific bits forced:

// Only needed for old environments without crypto.randomUUID.
// Builds a spec-compliant v4 UUID from 16 cryptographically-random bytes.
function uuidv4() {
  const b = crypto.getRandomValues(new Uint8Array(16));
  b[6] = (b[6] & 0x0f) | 0x40; // set the version nibble to 4
  b[8] = (b[8] & 0x3f) | 0x80; // set the variant bits to 10xx
  const h = [...b].map((x) => x.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('')
  );
}

The two bit-twiddling lines are the part worth understanding. b[6] = (b[6] & 0x0f) | 0x40 clears the high nibble of byte 6 and sets it to 4 — that's the "version 4" marker you can see as the digit after the second hyphen. b[8] = (b[8] & 0x3f) | 0x80 forces the top two bits of byte 8 to 10, the RFC 4122 "variant" — which is why the digit after the third hyphen is always 8, 9, a or b. Everything else stays random. Guard the fallback so it's only used when needed:

const uuid = crypto.randomUUID
  ? crypto.randomUUID()
  : uuidv4(); // fall back only where needed

The mistake to avoid: Math.random()

You'll see snippets that build a UUID-shaped string from Math.random(). Don't ship them. Math.random() is not a cryptographically secure source — it's seeded predictably and isn't designed to avoid collisions — so the result only looks like a UUID while losing the uniqueness guarantee that makes UUIDs worth using:

// DON'T: Math.random() is not cryptographically secure and
// produces predictable, collision-prone "UUIDs".
const notReallyUnique = 'xxxxxxxx'.replace(/x/g, () =>
  Math.floor(Math.random() * 16).toString(16),
);

Both crypto.randomUUID() and the fallback above draw from crypto.getRandomValues, the secure generator. That's what gives a v4 UUID its 122 bits of real randomness — enough that you'd need to mint billions per second for a century before a collision became likely.

Which version do I actually want?

crypto.randomUUID() gives you v4 (random), which is the right default for most uses: tokens, request IDs, client-generated keys. If you're using UUIDs as database primary keys and care about index locality, look at v7 (time-ordered) — it sorts by creation time, which indexes far better, though you'll currently need a small library for it. For everything else, v4 from the built-in API is all you need. If you're reaching for the same Web Crypto module to fingerprint data rather than to generate IDs, see hashing a string with SHA-256.

Frequently asked questions

How do I generate a UUID in JavaScript?
Call crypto.randomUUID(). It's built into every modern browser and into Node 16+, Deno, Bun and Cloudflare Workers, and returns a random version-4 UUID string — no library needed.
Is a UUID the same as a GUID?
Yes. GUID (globally unique identifier) is Microsoft’s name for the same 128-bit value; a UUID and a GUID are interchangeable, and crypto.randomUUID() produces a standard RFC 4122 version-4 value.
How do I generate a UUID in Node.js?
Node 16 and newer expose the same crypto.randomUUID() as the browser. On older versions, import it from the built-in crypto module: const { randomUUID } = require('crypto').
Why not build a UUID with Math.random()?
Math.random() isn't a cryptographically secure generator — it's seeded predictably and isn't designed to avoid collisions — so a Math.random()-based string only looks like a UUID while losing the uniqueness guarantee. Use crypto.randomUUID() or crypto.getRandomValues() instead.
Which UUID version should I use?
crypto.randomUUID() returns v4 (random), the right default for tokens, request IDs and client-generated keys. If you use UUIDs as database primary keys and care about index locality, consider time-ordered v7 instead.
Does crypto.randomUUID() work on http pages?
No. Web Crypto requires a secure context, so crypto.randomUUID() is defined on https:// pages and on localhost, but not on a plain http:// origin. In practice this only matters during local testing over an insecure origin.

Try it now: the UUID generator does everything in this guide in your browser — nothing is uploaded. Browse more guides or the full tool list.