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 generatorA 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.