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.
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.
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'
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';
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());
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();
You are building a new customer database where you expect millions of rows. You need IDs that are secure but also performant for indexing.
uuid (using v7)import { v7 } from 'uuid';
const customerId = v7();
You are auditing an older React codebase and find uuidv4 in package.json.
uuid// Before
import uuid from 'uuidv4';
// After
import { v4 as uuid } from 'uuid';
You need to generate unpredictable session tokens for users. Sortability is not required; randomness is key.
uuid (using v4)import { v4 } from 'uuid';
const sessionToken = v4();
| Feature | uuid | uuidv4 | uuidv7 |
|---|---|---|---|
| Status | β Active / Standard | β Deprecated | β οΈ Niche / Superseded |
| Versions Supported | v1, v3, v4, v5, v7 | v4 only | v7 only |
| Sortable IDs | Yes (via v7) | No | Yes |
| Tree-Shaking | β Excellent (Named Exports) | β Limited | β Good |
| Recommendation | Default Choice | Migrate Away | Use uuid instead |
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.
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.
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.
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.
For the creation of RFC9562 (formerly RFC4122) UUIDs
crypto API for random valuesuuid command line utility[!NOTE]
Starting with
uuid@12CommonJS is no longer supported. See implications and motivation for details.
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 ...
uuid.NIL | The nil UUID string (all zeros) |
uuid.MAX | The 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 |
The nil UUID string (all zeros).
Example:
import { NIL as NIL_UUID } from 'uuid';
NIL_UUID; // β¨ '00000000-0000-0000-0000-000000000000'
The max UUID string (all ones).
Example:
import { MAX as MAX_UUID } from 'uuid';
MAX_UUID; // β¨ 'ffffffff-ffff-ffff-ffff-ffffffffffff'
Convert UUID string to array of bytes
str | A valid UUID String |
| returns | Uint8Array[16] |
| throws | TypeError if str is not a valid UUID |
[!NOTE] Ordering of values in the byte arrays used by
parse()andstringify()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
// ]
Convert array of bytes to UUID string
arr | Array-like collection of 16 values (starting from offset) between 0-255. |
[offset = 0] | Number Starting index in the Array |
| returns | String |
| throws | TypeError if a valid UUID string cannot be generated |
[!NOTE] Ordering of values in the byte arrays used by
parse()andstringify()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'
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 |
| returns | UUID String if no buffer is specified, otherwise returns buffer |
| throws | Error 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'
Convert a UUID from version 1 to version 6
import { v1ToV6 } from 'uuid';
v1ToV6('92f62d9e-22c4-11ef-97e9-325096b39f47'); // β¨ '1ef22c49-2f62-6d9e-97e9-325096b39f47'
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."
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 |
| returns | UUID 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'
Create an RFC version 5 (namespace w/ SHA-1) UUID
name | String | Array |
namespace | String | 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 |
| returns | UUID String if no buffer is specified, otherwise returns buffer |
[!NOTE] The RFC
DNSandURLnamespaces are available asv5.DNSandv5.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'
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'
Convert a UUID from version 6 to version 1
import { v6ToV1 } from 'uuid';
v6ToV1('1ef22c49-2f62-6d9e-97e9-325096b39f47'); // β¨ '92f62d9e-22c4-11ef-97e9-325096b39f47'
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 |
| returns | UUID String if no buffer is specified, otherwise returns buffer |
Example:
import { v7 as uuidv7 } from 'uuid';
uuidv7(); // β¨ '01941f29-7c00-73e4-a310-744d2167fc5b'
"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. Thevalidate()andversion()methods do work with such UUIDs, however.
Test a string to see if it is a valid UUID
str | String to validate |
| returns | true 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
Detect RFC version of a UUID
str | A valid UUID String |
| returns | Number The RFC version of the UUID |
| throws | TypeError 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
0for theNILUUID, and15for theMAXUUID.
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 UUIDsPrior 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:
options: Internal state is utilized to improve UUID uniqueness.options: Internal state is NOT used and, instead, appropriate defaults are applied as needed.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
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-get-random-valuesuuid. 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