Make 🏗️ Devs

Cover Image for Generating UUID's in the Browser

Generating UUID's in the Browser

Jamie Vaughn
Jamie Vaughn

Sometimes there is a need to generate an id for objects created in the browser. Simply using an index or a number generated from Math.random() does not ensure an adequate level of uniqueness. What is really needed is a Universally Unique IDentifier (UUID). A UUID is a special id that garauntees uniqueness across all space and time.

A UUID is 128 bits long, and can guarantee uniqueness across space and time. UUIDs were originally used in the Apollo Network Computing System and later in the Open Software Foundation's (OSF) Distributed Computing Environment (DCE), and then in Microsoft Windows platforms.

source

There is a specification for the File API in the browser that generates UUID's according to the above requirements which ensures universal uniqueness. The browsers use it when creating blob for naming URLs for file resource locations.

It generates a URL that contains a UUID as part of the string as specificed in the File API spcification on step 9 of the procedure for generating a new blob URL.

An example of a blob URL that can be generated by this algorithm is blob:https://example.org/40a5fb5a-d56d-4a33-b4e2-0acf6a8e5f641.

With a tiny bit of cleverness, we can leverage that feature ourselves to use it for generating UUIDs as IDs for our own objects. And it can be done with a very terse function as well!

First, Let's See It In Action!

Click the button to generate a UUID

GenUUID

The Implementation

The implementation depends on instantiating a new Blob() and then passing that to the browser API URL.createObjectURL(). That will generate a url with a UUID in it, as seen previously. We can then use some string and array manipulation to extract out just the UUID from the URL.

// create the URL
URL.createObjectURL(new Blob());
// output: 'blob:https://example.org/40a5fb5a-d56d-4a33-b4e2-0acf6a8e5f641'

So to grab just the UUID from the end of that blob we can use the split method. If we split the string on the / character then it will always create an array of 4 elements with the element at position 3 containing the UUID that we are after:

URL.createObjectURL(new Blob()).split("/")[3];
// output: '40a5fb5a-d56d-4a33-b4e2-0acf6a8e5f641'

To avoid memory leaks we will also want to be sure to call URL.revokeObjectURL and pass it a reference to the URL blob we created.

Let's see how it looks packaged up into a reusable function:

const uuid = () => {
  let url = URL.createObjectURL(new Blob());
  URL.revokeObjectURL(url);
  return url.split("/")[3];
};

For fun, we could play some "code golf" with it and shorten that function up a bit more:

const uuid = (url = URL.createObjectURL(new Blob())) =>
  URL.revokeObjectURL(url) || url.split("/")[3];

Just make sure to invoke that function with no parameters passed so the default value is used for the url parameter. Also note that the URL.createObjectURL API is available in Web Workers (but not in Service Workers).