[Proposal] RFC4122 v4 UUIDs

tldr; I would like to revisit, and make a case for, RFC4122 v4 UUIDs. Here’s the start of a proposal: bcoe.github.io/uuid/.

v4 UUIDs are ubiquitous

As Marcos points out in the post “Add UUIDs API to the platform”, uuid is one of the most widely used modules in the JavaScript ecosystem:

uuid is a dependency of over 30,000 modules on npm, and downloaded 40,000,000 times a week (In analyis summarized here, it was found that about 80% of users of the library use the v4 algorithm).

v4 uuid’s have a wide variety of uses, once you start looking for them you see them everywhere:

  • identifiers for request tracing (potentially frontend through to server).
  • a method for anonymously tracking page views.
  • a temporary document name, e.g., a Google sheet generated as the output of a report.
  • resource names in unit tests.
  • identifiers for inspector sessions.
  • identifiers on physical items, such as shipping receipts.
  • identifiers for IoT devices.

Bad implementations of UUID v4 are a risk to developers

Developers who have not been exposed to RFC 4122 might naturally opt to invent their own approaches to UUID generation.

TIFU by using Math.random() is a good discussion of why it’s important that UUIDs are generated using a sound algorithm, with a secure source of randomness.

When I disussed this with a colleague today, they had a great quote:

well I don’t want to write any kind of hash- or crypto-related code even it’s just 40 lines

Folks are excited about this idea

Christoph Tavan and Robert Kieffer the two main maintainers of uuid are excited about the prospect of making RFC4122 UUID generation available to the web and other JavaScript platforms, and have been helping flesh out the proposal.

We just shipped WebCrypto on the Node.js project, and we’re likewise excited to add UUID support as a natual extension to this functionality – we’d love to do so in a platform agnostic way.

3 Likes

Another example of where it would be very nice to have a built in UUID implementation:

My team at Google writes samples that are then embedded throughout documentation, we attempt to ensure that these dependencies have no external dependencies.

I’ve got a PR against that TC39 repo with an updated download count + dependent repo count: https://github.com/tc39/proposal-uuid/pull/39

I also compared it to Lodash’s core module in popularity and usage, and found some interesting findings.

Hi there! I’m one of the maintainers of the uuid module at https://github.com/uuidjs/uuid

Historically our uuid implementation was using a Math.random() based fallback RNG for environments where no CSPRNG was available.

When we dropped that (happened in the v3 -> v7 version bump) it became apparent that react-native was one such environment. Affected developers quickly suggested to fall back to insecure random number generators again for convenience, which I always advocated against! It has ultimately caused quite some effort across a couple of projects (namely uuid, react-native-get-random-values und expo) to fix this situation for react-native users, see e.g. https://github.com/LinusU/react-native-get-random-values/pull/13

Another issue that keeps popping up is that we currently ship two variants of the module, one for Node.js which uses the Node.js crypto core module and one for Browsers that uses WebCrypto. This also keeps causing trouble for folks who happen to configure their bundlers (rollup/webpack) in a bad way, leading those bundlers to pick the wrong source files for the respective target environments (https://github.com/uuidjs/uuid/issues/516, https://github.com/uuidjs/uuid/issues/482, https://github.com/uuidjs/uuid/issues/314, https://github.com/uuidjs/uuid/issues/544).

Given the convergence of Node.js core APIs and Web APIs towards Web APIs (Node.js recently started exposing the WebCrypto API https://nodejs.org/dist/latest-v15.x/docs/api/webcrypto.html) the situation around Crypto APIs may improve for the uuid library.

However, given this de-facto convergence towards Web APIs in related areas I believe that it makes a lot of sense to consider standardizing UUID as a web API.

2 Likes

We can absolutely support a standard api for this in node.js. There are some folks who would argue that a userland module would be preferred but having the support of the author of the most popular such module currently goes a long way towards handling that argument. Is version 4 all we need?

Is version 4 all we need?

In our research, it jumped out that:

  • 77% to 90% of applications we found using node-uuid were using version 4.
  • some of the outliers using v1 (which requires a node ID) would have been better suited to v4; choosing an appropriate Node identifier is non-trivial (e.g., VMs share MAC addresses), and it’s often better to just populate all the bits with entropy.
  • v3/v5 are hashing algorithms (MD5 and SHA-1 respectively); they solve a slightly different problem than v1/v3, and are less widely used.

We landed on the method randomUUID() because:

  1. a random identifier seems to solve users’ most common need.
  2. we’re not locked in to v4, if a better algorithm eventually came along (mind you, I don’t see how this would be possible, since v4 fills all its bits with entropy, except reserved bits).