DEV Community

Cover image for NanoID - A URL Friendly Unique Identifier
Apoorv Tyagi
Apoorv Tyagi

Posted on • Originally published at apoorvtyagi.tech

NanoID - A URL Friendly Unique Identifier

Introduction

In every software system, we need unique Ids to distinguish between several objects from one another.

Recently, I wrote about the unique Id generation for a large scale distributed environment. In that article, we touched a little on UUIDs.

In this blog post, I will share an alternative to UUIDs that can help you fit the requirements that UUIDs fulfills and overcomes some of their shortcomings as well.

Introducing Nano ID

It is a tiny, secure, URL-friendly, unique string ID generator.

  • Nano ID has smaller size as compared to UUID. This size reduction impacts a lot. Making use of NanoID is easier for transferring information and storage space. In a large-scale system, these numbers can make a lot of difference.

  • NanoID uses a cryptographically strong API which is a lot safer compared to Math.Random() which are insecure. These API modules use unpredictable hardware generated random identifiers.

  • NanoID utilizes its very own "uniform formula" throughout the application of the ID generator instead of making use of an arbitrary "% alphabet" which is a popular mistake to make when coding an ID generator (The spread will not be even in some cases).

  • NanoID uses a larger alphabet resulting in short but unique identifiers.

  • NanoID permits designers to utilize personalized alphabets. This is another additional function of Nano ID. You can alter the literals or the dimension of the id as shown below: (Specifying personalized letter as '1234567890ABCDEF' & dimension of the Id as 10)

import { alphabet } from 'nanoid';
const nanoid = alphabet ('1234567890ABCDEF', 10);
model.id = nanoid();
Enter fullscreen mode Exit fullscreen mode
  • NanoID doesn’t much rely on any kind of third-party dependencies, which means, it ends up being a lot more steady which is helpful to maximize the package scope over time as well as make it much less vulnerable to the issues that come along with dependencies.

  • NanoID is available in various programs languages, which include - C#, C++, Dart & Flutter, Go, Java, PHP, Python, Ruby, Rust, Swift, etc.

Benchmark

image.png

Example usages

Generating both NanoID or UUID is pretty straightforward. In JavaScript, you have NPM packages that will help you to generate them. You can get NanoId from here => https://github.com/ai/nanoid

  • The main module uses URL-friendly symbols (A-Za-z0-9_-) and returns an ID with 21 characters:
    import { nanoid } from "nanoid";
    model.id = nanoid() // X2JaSYP7_Q2leGI9b-MyA
Enter fullscreen mode Exit fullscreen mode
  • You can also specify the number of characters you want:
    nanoid(9); // "wMeKBp6th"
Enter fullscreen mode Exit fullscreen mode
  • You can also change the used alphabet for generating hashes to your own if you have specific requirements as seen above:
    const alphabet = '0123456789ABCDEF';
    generate(alphabet, 9); // F65BF3050
Enter fullscreen mode Exit fullscreen mode

Risk of collision

Even though it can generate over 2.2 million unique IDs per second with its default alphabet, there is still a chance of generating the same multiple Ids.

But what are the odds of that happening?

You can calculate that based on the given parameters easily here and here.

You'll notice that this probability comes out to be extremely small.

Some disadvantages

Even though NanoId is considered better than UUIDs, it still has some limitations:

  • Being non-human readable is the main disadvantage.

Imagine that a customer calls and is asked to provide the identifier, having to spell a complete NanoID is not a pleasant experience. When compared to UUID, NanoID is way shorter and readable but still cannot be used in such cases where the end customer needs to use it.

  • It can't be used as primary key in any SQL Database tables

If you use NanoID as a table’s primary key, there will be problems if you use the same column as a clustered index. This is because NanoIDs are not sequential.


A few words of wisdom

Any approach in a Software World is always going to be subjective. It’s up to your requirements to weigh in the tradeoffs and choose the approach that works for you. No design is concrete enough to continue forever, so given the constraints, we have chosen a certain design, and depending on how it works for us we might evolve it further as well.

👋 Thanks for reading and Happy learning…

Top comments (0)