uuid vs uuidv4 vs uuidv7
Generating Unique Identifiers in Modern JavaScript Applications
uuiduuidv4uuidv7Similar Packages:

Generating Unique Identifiers in Modern JavaScript Applications

The uuid, uuidv4, and uuidv7 packages all provide solutions for generating Universally Unique Identifiers (UUIDs), but they serve different stages of the UUID evolution and offer varying levels of flexibility.

uuid is the comprehensive, industry-standard library that supports multiple UUID versions (v1, v3, v4, v5, and v7) and runs in both Node.js and browser environments. It is the most robust choice for complex systems requiring specific UUID strategies.

uuidv4 is a legacy, single-purpose package dedicated solely to generating Version 4 (random) UUIDs. It is no longer actively maintained and has been officially deprecated in favor of the main uuid package.

uuidv7 is a specialized utility focused exclusively on generating Version 7 UUIDs, which embed a Unix timestamp to ensure sortability. While useful for specific database indexing needs, its functionality is now largely superseded by the native support for v7 within the main uuid package.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
uuid015,32165.7 kB012 days agoMIT
uuidv40-17.4 kB--MIT
uuidv7026975.8 kB05 months agoApache-2.0

UUID Generation Strategies: uuid vs uuidv4 vs uuidv7

Generating unique identifiers is a fundamental requirement in distributed systems, database design, and frontend state management. While the concept of a UUID (Universally Unique Identifier) is standardized, the JavaScript packages implementing them vary significantly in maintenance status, feature set, and architectural intent. Let's break down the differences between the industry-standard uuid, the legacy uuidv4, and the specialized uuidv7.

πŸ—οΈ Architecture and Scope: The All-in-One vs. Single-Purpose

The most critical distinction lies in the scope of each library. Modern architecture favors modular, versatile tools over single-function scripts.

uuid is a comprehensive toolkit. It doesn't just do one thing; it implements the entire RFC 4122 standard (and newer drafts). It allows you to generate IDs based on random numbers, timestamps, or namespace hashing. Crucially, it is designed for tree-shaking, meaning your build tool can exclude the code for versions you don't use.

// uuid: Modular imports for specific versions
import { v4 as uuidv4, v7 as uuidv7 } from 'uuid';

const randomId = uuidv4();
const sortableId = uuidv7();

uuidv4 is a single-purpose script. It was created when the main uuid library was heavier and less modular. Today, it serves only one function: generating random UUIDs. It lacks support for any other version.

// uuidv4: Default export is the generator function
import uuidv4 from 'uuidv4';

const id = uuidv4();
// No other versions available

uuidv7 is a specialized tool for a specific problem: sortability. Version 7 UUIDs embed a Unix timestamp, making them naturally ordered by time. This package isolates that logic but, like uuidv4, lacks the broader ecosystem of the main library.

// uuidv7: Dedicated to time-sortable IDs
import { generate } from 'uuidv7';

const orderedId = generate();
// Returns a string like '017f22e2-79b0-7cc3-98c4-dc0c0c0c0c0c'

⚠️ Maintenance Status: Active vs. Deprecated

In professional engineering, relying on unmaintained software is a security risk. The status of these packages is the most decisive factor in your choice.

uuid is actively maintained. It receives regular updates for security patches, browser compatibility, and new standards (like the recent addition of v7). The maintainers explicitly recommend it as the primary source for all UUID needs.

// uuid: Regularly updated to support new environments
import { v4 } from 'uuid';
// Works seamlessly in Node.js 18+, Deno, Bun, and all modern browsers

uuidv4 is deprecated. The npm page and GitHub repository clearly state that this package is no longer maintained. The authors direct all users to migrate to uuid. Using it means you are on your own if a vulnerability is discovered.

// uuidv4: DEPRECATED
// npm install uuidv4 
// Warning: This package is deprecated. Use 'uuid' instead.
import uuid from 'uuidv4'; // Avoid this in new code

uuidv7 has limited maintenance momentum. While not always marked with a big red "deprecated" banner depending on the specific fork, its primary value proposition (generating v7 IDs) has been absorbed by the main uuid package. Relying on a niche package for a feature now available in the standard library creates unnecessary fragmentation.

// uuidv7: Functionality now native to 'uuid'
// Prefer importing from the main package
import { v7 } from 'uuid'; 

πŸ“… Sorting and Ordering: Random vs. Time-Based

Database performance often hinges on how IDs are indexed. Random IDs cause page splits in B-Tree indexes, while time-based IDs append cleanly to the end.

uuid (v4) generates purely random IDs. They are great for security (unpredictable) but terrible for database insertion performance at scale because they are not sorted.

// uuid v4: Random order
// Output: '550e8400-e29b-41d4-a716-446655440000'
// Next output: '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d' (No relation to previous)
import { v4 } from 'uuid';
console.log(v4());

uuid (v7) and uuidv7 both solve the sorting problem. They embed the current timestamp in the first bits of the ID. This means IDs generated later are numerically larger, allowing for efficient database indexing.

// uuid v7: Time-ordered
// Output: '017f22e2-79b0-7cc3-98c4-dc0c0c0c0c0c'
// Next output (1ms later): '017f22e2-79b0-7cc4-...' (Incremented)
import { v7 } from 'uuid';
console.log(v7());

// uuidv7: Same result, different package
import { generate } from 'uuidv7';
console.log(generate());

πŸ› οΈ API Ergonomics and Tree-Shaking

How you import and use these libraries affects your final bundle size and code readability.

uuid uses named exports. This is the modern standard. It enables build tools like Webpack, Vite, and Rollup to perform tree-shaking, removing unused code from your final bundle automatically.

// uuid: Named exports enable tree-shaking
import { v1, v4, v5, v7 } from 'uuid';

// If you only use v4, the code for v1, v5, and v7 is removed from your bundle
const id = v4();

uuidv4 typically uses a default export. While simple, it offers no granularity. You import the whole package even if you just need the function, though the package itself is small.

// uuidv4: Default export
import uuid from 'uuidv4';

const id = uuid();

uuidv7 varies by implementation but often provides a named generate function. However, since uuid now offers the same API shape (v7), there is no ergonomic advantage to using the standalone package.

// uuidv7: Named export
import { generate } from 'uuidv7';

const id = generate();

🌐 Real-World Scenarios

Scenario 1: New SaaS Application Database

You are building a new customer database where you expect millions of rows. You need IDs that are secure but also performant for indexing.

  • βœ… Best choice: uuid (using v7)
  • Why? You get the performance benefits of time-sortable IDs with the guarantee of an actively maintained library.
import { v7 } from 'uuid';
const customerId = v7();

Scenario 2: Legacy Frontend Migration

You are auditing an older React codebase and find uuidv4 in package.json.

  • βœ… Action: Replace with uuid
  • Why? The package is deprecated. The migration is trivial and improves security posture.
// Before
import uuid from 'uuidv4';

// After
import { v4 as uuid } from 'uuid';

Scenario 3: Session Tokens

You need to generate unpredictable session tokens for users. Sortability is not required; randomness is key.

  • βœ… Best choice: uuid (using v4)
  • Why? Version 4 is the standard for randomness. The main library is the trusted source.
import { v4 } from 'uuid';
const sessionToken = v4();

πŸ“Œ Summary Table

Featureuuiduuidv4uuidv7
Statusβœ… Active / Standard❌ Deprecated⚠️ Niche / Superseded
Versions Supportedv1, v3, v4, v5, v7v4 onlyv7 only
Sortable IDsYes (via v7)NoYes
Tree-Shakingβœ… Excellent (Named Exports)❌ Limitedβœ… Good
RecommendationDefault ChoiceMigrate AwayUse uuid instead

πŸ’‘ Final Recommendation

The decision matrix here is straightforward. uuid is the clear winner for any professional project. It consolidates the functionality of the other two packages into a single, well-maintained dependency.

Avoid uuidv4 entirely; it is technical debt waiting to happen. Similarly, while uuidv7 solves a real problem (sorting), that solution is now part of the main uuid standard. By choosing uuid, you ensure your team has access to the latest security updates, consistent API patterns, and the flexibility to switch UUID strategies (e.g., from v4 to v7) without changing dependencies.

How to Choose: uuid vs uuidv4 vs uuidv7

  • uuid:

    Choose uuid for any new production project requiring reliable, cross-platform unique ID generation. It is the only actively maintained option among the three and supports the full spectrum of UUID versions, including the modern, sortable Version 7. Its modular architecture allows you to import only the specific generator you need, keeping bundle sizes efficient while ensuring long-term security and compatibility.

  • uuidv4:

    Do NOT choose uuidv4 for new projects. This package is deprecated and no longer receives security updates or maintenance. Its sole functionality (generating random UUIDs) is fully available within the main uuid package via uuid.v4(). Continuing to use this legacy dependency introduces unnecessary risk and technical debt without providing any unique benefits.

  • uuidv7:

    Choose uuidv7 only if you are maintaining a legacy codebase that explicitly depends on this standalone package and cannot yet migrate. For all new development requiring sortable, time-ordered UUIDs, you should instead use the uuid.v7() method provided by the main uuid package, which offers the same algorithm with better maintenance guarantees and consistent API design.

README for uuid

uuid CI Browser

For the creation of RFC9562 (formerly RFC4122) UUIDs

[!NOTE]

Starting with uuid@12 CommonJS is no longer supported. See implications and motivation for details.

Quickstart

1. Install

npm install uuid

2. Create a UUID

import { v4 as uuidv4 } from 'uuid';

uuidv4(); // ⇨ 'b18794e8-5d0d-417c-b361-ba38e78411b4'

For timestamp UUIDs, namespace UUIDs, and other options read on ...

API Summary

uuid.NILThe nil UUID string (all zeros)
uuid.MAXThe max UUID string (all ones)
uuid.parse()Convert UUID string to array of bytes
uuid.stringify()Convert array of bytes to UUID string
uuid.v1()Generate a version 1 (timestamp) UUID
uuid.v1ToV6()Convert a version 1 UUID to version 6
uuid.v3()Generate a version 3 (namespace w/ MD5) UUID
uuid.v4()Generate a version 4 (random) UUID
uuid.v5()Generate a version 5 (namespace w/ SHA-1) UUID
uuid.v6()Generate a version 6 (timestamp, reordered) UUID
uuid.v6ToV1()Convert a version 6 UUID to version 1
uuid.v7()Generate a version 7 (Unix Epoch time-based) UUID
uuid.v8()"Intentionally left blank"
uuid.validate()Test a string to see if it is a valid UUID
uuid.version()Detect RFC version of a UUID

API

uuid.NIL

The nil UUID string (all zeros).

Example:

import { NIL as NIL_UUID } from 'uuid';

NIL_UUID; // ⇨ '00000000-0000-0000-0000-000000000000'

uuid.MAX

The max UUID string (all ones).

Example:

import { MAX as MAX_UUID } from 'uuid';

MAX_UUID; // ⇨ 'ffffffff-ffff-ffff-ffff-ffffffffffff'

uuid.parse(str)

Convert UUID string to array of bytes

strA valid UUID String
returnsUint8Array[16]
throwsTypeError if str is not a valid UUID

[!NOTE] Ordering of values in the byte arrays used by parse() and stringify() follows the left β†  right order of hex-pairs in UUID strings. As shown in the example below.

Example:

import { parse as uuidParse } from 'uuid';

// Parse a UUID
uuidParse('6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b'); // ⇨
// Uint8Array(16) [
//   110, 192, 189, 127,  17,
//   192,  67, 218, 151,  94,
//    42, 138, 217, 235, 174,
//    11
// ]

uuid.stringify(arr[, offset])

Convert array of bytes to UUID string

arrArray-like collection of 16 values (starting from offset) between 0-255.
[offset = 0]Number Starting index in the Array
returnsString
throwsTypeError if a valid UUID string cannot be generated

[!NOTE] Ordering of values in the byte arrays used by parse() and stringify() follows the left β†  right order of hex-pairs in UUID strings. As shown in the example below.

Example:

import { stringify as uuidStringify } from 'uuid';

const uuidBytes = Uint8Array.of(
  0x6e,
  0xc0,
  0xbd,
  0x7f,
  0x11,
  0xc0,
  0x43,
  0xda,
  0x97,
  0x5e,
  0x2a,
  0x8a,
  0xd9,
  0xeb,
  0xae,
  0x0b
);

uuidStringify(uuidBytes); // ⇨ '6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b'

uuid.v1([options[, buffer[, offset]]])

Create an RFC version 1 (timestamp) UUID

[options]Object with one or more of the following properties:
[options.node = (random) ]RFC "node" field as an Array[6] of byte values (per 4.1.6)
[options.clockseq = (random)]RFC "clock sequence" as a Number between 0 - 0x3fff
[options.msecs = (current time)]RFC "timestamp" field (Number of milliseconds, unix epoch)
[options.nsecs = 0]RFC "timestamp" field (Number of nanoseconds to add to msecs, should be 0-10,000)
[options.random = (random)]Array of 16 random bytes (0-255) used to generate other fields, above
[options.rng]Alternative to options.random, a Function that returns an Array of 16 random bytes (0-255)
[buffer]Uint8Array or Uint8Array subtype (e.g. Node.js Buffer). If provided, binary UUID is written into the array, starting at offset
[offset = 0]Number Index to start writing UUID bytes in buffer
returnsUUID String if no buffer is specified, otherwise returns buffer
throwsError if more than 10M UUIDs/sec are requested

Example:

import { v1 as uuidv1 } from 'uuid';

uuidv1(); // ⇨ '57fd0000-c7d3-11ef-841d-514d2167fc5b'

Example using options:

import { v1 as uuidv1 } from 'uuid';

const options = {
  node: Uint8Array.of(0x01, 0x23, 0x45, 0x67, 0x89, 0xab),
  clockseq: 0x1234,
  msecs: new Date('2011-11-01').getTime(),
  nsecs: 5678,
};
uuidv1(options); // ⇨ '710b962e-041c-11e1-9234-0123456789ab'

uuid.v1ToV6(uuid)

Convert a UUID from version 1 to version 6

import { v1ToV6 } from 'uuid';

v1ToV6('92f62d9e-22c4-11ef-97e9-325096b39f47'); // ⇨ '1ef22c49-2f62-6d9e-97e9-325096b39f47'

uuid.v3(name, namespace[, buffer[, offset]])

Create an RFC version 3 (namespace w/ MD5) UUID

API is identical to v5(), but uses "v3" instead.

[!IMPORTANT] Per the RFC, "If backward compatibility is not an issue, SHA-1 [Version 5] is preferred."

uuid.v4([options[, buffer[, offset]]])

Create an RFC version 4 (random) UUID

[options]Object with one or more of the following properties:
[options.random]Array of 16 random bytes (0-255)
[options.rng]Alternative to options.random, a Function that returns an Array of 16 random bytes (0-255)
[buffer]Uint8Array or Uint8Array subtype (e.g. Node.js Buffer). If provided, binary UUID is written into the array, starting at offset
[offset = 0]Number Index to start writing UUID bytes in buffer
returnsUUID String if no buffer is specified, otherwise returns buffer

Example:

import { v4 as uuidv4 } from 'uuid';

uuidv4(); // ⇨ 'b18794e8-5d0d-417c-b361-ba38e78411b4'

Example using predefined random values:

import { v4 as uuidv4 } from 'uuid';

const v4options = {
  random: Uint8Array.of(
    0x10,
    0x91,
    0x56,
    0xbe,
    0xc4,
    0xfb,
    0xc1,
    0xea,
    0x71,
    0xb4,
    0xef,
    0xe1,
    0x67,
    0x1c,
    0x58,
    0x36
  ),
};
uuidv4(v4options); // ⇨ '109156be-c4fb-41ea-b1b4-efe1671c5836'

uuid.v5(name, namespace[, buffer[, offset]])

Create an RFC version 5 (namespace w/ SHA-1) UUID

nameString | Array
namespaceString | Array[16] Namespace UUID
[buffer]Uint8Array or Uint8Array subtype (e.g. Node.js Buffer). If provided, binary UUID is written into the array, starting at offset
[offset = 0]Number Index to start writing UUID bytes in buffer
returnsUUID String if no buffer is specified, otherwise returns buffer

[!NOTE] The RFC DNS and URL namespaces are available as v5.DNS and v5.URL.

Example with custom namespace:

import { v5 as uuidv5 } from 'uuid';

// Define a custom namespace.  Readers, create your own using something like
// https://www.uuidgenerator.net/
const MY_NAMESPACE = '1b671a64-40d5-491e-99b0-da01ff1f3341';

uuidv5('Hello, World!', MY_NAMESPACE); // ⇨ '630eb68f-e0fa-5ecc-887a-7c7a62614681'

Example with RFC URL namespace:

import { v5 as uuidv5 } from 'uuid';

uuidv5('https://www.w3.org/', uuidv5.URL); // ⇨ 'c106a26a-21bb-5538-8bf2-57095d1976c1'

uuid.v6([options[, buffer[, offset]]])

Create an RFC version 6 (timestamp, reordered) UUID

This method takes the same arguments as uuid.v1().

import { v6 as uuidv6 } from 'uuid';

uuidv6(); // ⇨ '1efc7d35-7fd0-6000-841d-504d2167fc5b'

Example using options:

import { v6 as uuidv6 } from 'uuid';

const options = {
  node: [0x01, 0x23, 0x45, 0x67, 0x89, 0xab],
  clockseq: 0x1234,
  msecs: new Date('2011-11-01').getTime(),
  nsecs: 5678,
};
uuidv6(options); // ⇨ '1e1041c7-10b9-662e-9234-0123456789ab'

uuid.v6ToV1(uuid)

Convert a UUID from version 6 to version 1

import { v6ToV1 } from 'uuid';

v6ToV1('1ef22c49-2f62-6d9e-97e9-325096b39f47'); // ⇨ '92f62d9e-22c4-11ef-97e9-325096b39f47'

uuid.v7([options[, buffer[, offset]]])

Create an RFC version 7 (random) UUID

[options]Object with one or more of the following properties:
[options.msecs = (current time)]RFC "timestamp" field (Number of milliseconds, unix epoch)
[options.random = (random)]Array of 16 random bytes (0-255) used to generate other fields, above
[options.rng]Alternative to options.random, a Function that returns an Array of 16 random bytes (0-255)
[options.seq = (random)]32-bit sequence Number between 0 - 0xffffffff. This may be provided to help ensure uniqueness for UUIDs generated within the same millisecond time interval. Default = random value.
[buffer]Uint8Array or Uint8Array subtype (e.g. Node.js Buffer). If provided, binary UUID is written into the array, starting at offset
[offset = 0]Number Index to start writing UUID bytes in buffer
returnsUUID String if no buffer is specified, otherwise returns buffer

Example:

import { v7 as uuidv7 } from 'uuid';

uuidv7(); // ⇨ '01941f29-7c00-73e4-a310-744d2167fc5b'

uuid.v8()

"Intentionally left blank"

[!NOTE] Version 8 (experimental) UUIDs are "for experimental or vendor-specific use cases". The RFC does not define a creation algorithm for them, which is why this package does not offer a v8() method. The validate() and version() methods do work with such UUIDs, however.

uuid.validate(str)

Test a string to see if it is a valid UUID

strString to validate
returnstrue if string is a valid UUID, false otherwise

Example:

import { validate as uuidValidate } from 'uuid';

uuidValidate('not a UUID'); // ⇨ false
uuidValidate('6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b'); // ⇨ true

Using validate and version together it is possible to do per-version validation, e.g. validate for only v4 UUIds.

import { version as uuidVersion } from 'uuid';
import { validate as uuidValidate } from 'uuid';

function uuidValidateV4(uuid) {
  return uuidValidate(uuid) && uuidVersion(uuid) === 4;
}

const v1Uuid = 'd9428888-122b-11e1-b85c-61cd3cbb3210';
const v4Uuid = '109156be-c4fb-41ea-b1b4-efe1671c5836';

uuidValidateV4(v4Uuid); // ⇨ true
uuidValidateV4(v1Uuid); // ⇨ false

uuid.version(str)

Detect RFC version of a UUID

strA valid UUID String
returnsNumber The RFC version of the UUID
throwsTypeError if str is not a valid UUID

Example:

import { version as uuidVersion } from 'uuid';

uuidVersion('45637ec4-c85f-11ea-87d0-0242ac130003'); // ⇨ 1
uuidVersion('6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b'); // ⇨ 4

[!NOTE] This method returns 0 for the NIL UUID, and 15 for the MAX UUID.

Command Line

UUIDs can be generated from the command line using uuid.

$ npx uuid
ddeb27fb-d9a0-4624-be4d-4615062daed4

The default is to generate version 4 UUIDS, however the other versions are supported. Type uuid --help for details:

$ npx uuid --help

Usage:
  uuid
  uuid v1
  uuid v3 <name> <namespace uuid>
  uuid v4
  uuid v5 <name> <namespace uuid>
  uuid v7
  uuid --help

Note: <namespace uuid> may be "URL" or "DNS" to use the corresponding UUIDs
defined by RFC9562

options Handling for Timestamp UUIDs

Prior to uuid@11, it was possible for options state to interfere with the internal state used to ensure uniqueness of timestamp-based UUIDs (the v1(), v6(), and v7() methods). Starting with uuid@11, this issue has been addressed by using the presence of the options argument as a flag to select between two possible behaviors:

  • Without options: Internal state is utilized to improve UUID uniqueness.
  • With options: Internal state is NOT used and, instead, appropriate defaults are applied as needed.

Support

Browsers: uuid builds are tested against the latest version of desktop Chrome, Safari, Firefox, and Edge. Mobile versions of these same browsers are expected to work but aren't currently tested.

Node: uuid builds are tested against node (LTS releases), plus one prior. E.g. At the time of this writing node@20 is the "maintenance" release and node@24 is the "current" release, so uuid supports node@20-node@24.

Typescript: TS versions released within the past two years are supported. source

Known issues

"getRandomValues() not supported"

This error occurs in environments where the standard crypto.getRandomValues() API is not supported. This issue can be resolved by adding an appropriate polyfill:

React Native / Expo

  1. Install react-native-get-random-values
  2. Import it before uuid. Since uuid might also appear as a transitive dependency of some other imports it's safest to just import react-native-get-random-values as the very first thing in your entry point:
import 'react-native-get-random-values';
import { v4 as uuidv4 } from 'uuid';

Generated from README_js.md by runmd