Inspired by the following parent project: ai's nanoid
A tiny, secure, URL-friendly, unique string ID generator for Deno.
“An amazing level of senseless perfectionism, which is simply impossible not to respect.”
- Safe. It uses hardware random generator. Can be used in clusters.
- Short IDs. It uses a larger alphabet than UUID (
A-Za-z0-9_-
). So ID size was reduced from 36 to 21 symbols. - Portable. Nano ID was ported to over 20 programming languages.
The safe and easiest way to use Nano ID.
Add the module:
deno add @qz/nanoid-deno
Then, you can use the module in your code like this:
import { nanoid } from "@qz/nanoid-deno";
const id = nanoid(); //=> "Uakgb_J5m9g-0JDMbcJqL"
In rare cases, it could block the CPU from other tasks while it's collecting noise for the hardware random generator.
Nano ID is quite comparable to UUID v4 (random-based). It has a similar number of random bits in the ID (126 in Nano ID and 122 in UUID), so it has a similar collision probability:
For there to be a one in a billion chance of duplication, 103 trillion version 4 IDs must be generated.
Nano ID uses a bigger alphabet, so it packs in a similar number of random bits in just 21 symbols instead of 36.
See a good article about random generators theory: Secure random values (in Node.js)
-
Unpredictability. Instead of using the unsafe
Math.random()
, Nano ID uses thecrypto
module in Deno. These modules use unpredictable hardware random generator. -
Uniformity.
random % alphabet
is a popular mistake to make when coding an ID generator. The distribution will not be even; there will be a lower chance for some symbols to appear compared to others. So, it will reduce the number of tries when brute-forcing. Nano ID uses a better algorithm and is tested for uniformity. -
Well-documented: All Nano ID hacks are documented. See comments in the source code.
-
Vulnerabilities: to report a security vulnerability, please use the Tidelift security contact. Tidelift will coordinate the fix and disclosure.
Nano ID has 2 APIs: normal and non-secure.
By default, Nano ID uses URL-friendly symbols (A-Za-z0-9_-
) and returns an ID
with 21 characters. (to have a collision probability similar to UUID v4).
If you want to reduce the ID size (and increase collisions probability), you can pass the size as an argument.
nanoid(10); //=> "IRFa-VaY2b"
Don’t forget to check the safety of your ID size in our ID collision probability calculator.
You can also use a custom alphabet or a random generator.
By default, Nano ID uses hardware random bytes generation for security and low collision probability. If you are not so concerned with security, you can use it for environments without hardware random generators.
import { nanoid } from "@qz/nanoid-deno/non_secure";
const id = nanoid(); //=> "Uakgb_J5m9g-0JDMbcJqLJ"
customAlphabet
returns a function that allows you to create nanoid
with your
own alphabet and ID size.
import { customAlphabet } from "@qz/nanoid-deno";
const nanoid = customAlphabet("1234567890abcdef", 10);
const id = nanoid(); //=> "4f90d13a42"
Check the safety of your custom alphabet and ID size in our
ID collision probability
calculator. For more alphabets, check out the options
in nanoid-dictionary
.
Alphabet must contain 256 symbols or less. Otherwise, the security of the internal generator algorithm is not guaranteed.
In addition to setting a default size, you can change the ID size when calling the function:
import { customAlphabet } from "@qz/nanoid-deno";
const nanoid = customAlphabet("1234567890abcdef", 10);
const id = nanoid(5); //=> "f01a2"
customRandom
allows you to create a nanoid
and replace alphabet and the
default random bytes generator.
In this example, a seed-based generator is used:
import { customRandom } from "@qz/nanoid-deno";
const rng = seedrandom(seed);
const nanoid = customRandom("abcdef", 10, (size) => {
return (new Uint8Array(size)).map(() => 256 * rng());
});
const id = nanoid(); //=> "fbaefaadeb"
random
callback must accept the array size and return an array with random
numbers.
If you want to use the same URL-friendly symbols with customRandom
, you can
get the default alphabet using the urlAlphabet
.
import { customRandom, urlAlphabet } from "@qz/nanoid-deno";
const nanoid = customRandom(urlAlphabet, 10, myRandomGenerator);
Note, that between Nano ID versions we may change random generator call sequence. If you are using seed-based generators, we do not guarantee the same result.
To generate a unique ID in the terminal, you can simply run this command:
$ deno run jsr:@qz/nanoid-deno/cli
LZfXLFzPPR4NNrgjlWDxn
For easier access, you can install nanoid-deno globally on your machine with this command:
$ deno install --global -n nanoid jsr:@qz/nanoid-deno/cli
✅ Successfully installed nanoid
/home/qz/.deno/bin/nanoid
Once installed, you can generate IDs by just typing nanoid
:
$ nanoid
LZfXLFzPPR4NNrgjlWDxn
If you ever need to remove the package, you can do so with this command:
$ deno uninstall --global nanoid
deleted /home/qz/.deno/bin/nanoid
✅ Successfully uninstalled nanoid
You can also customize the the length of the generated ID using the --size
(or
-s
) option:
$ nanoid --size 10
L3til0JS4z
To create IDs with a specific set of characters, use the --alphabet
(or -a
)
option along with --size
:
$ nanoid --alphabet abc --size 15
bccbcabaabaccab
Nano ID was ported to many languages. You can use these ports to have the same ID generator on the client and server side.
- C#
- C++
- Clojure and ClojureScript
- ColdFusion/CFML
- Crystal
- Dart & Flutter
- Deno:
- nanoid-deno (this project)
- nanoid
- Elixir
- Go
- Haskell
- Haxe
- Janet
- Java
- Kotlin
- MySQL/MariaDB
- Nim
- OCaml
- Perl
- PHP
- Python native implementation with dictionaries and fast implementation (written in Rust)
- Postgres Extension and Native Function
- R (with dictionaries)
- Ruby
- Rust
- Swift
- Unison
- V
- Zig
- ID size calculator shows collision probability when adjusting the ID alphabet or size.
nanoid-dictionary
with popular alphabets to use withcustomAlphabet
.nanoid-good
to be sure that your ID doesn’t contain any obscene words.