unique-custom-id
Version:
β‘οΈ Generate custom IDs like never before β fast, secure, and fully yours! π₯
495 lines (375 loc) β’ 11.7 kB
Markdown
# π UCID





π _UCID stands for Unique Custom ID, the easiest, fastest, and most customizable ID generator you'll ever meet!_
## π‘ Why UCID?
Because it's...
- πΏ **Compact** β [Zero dependencies](https://www.npmjs.com/package/unique-custom-id?activeTab=dependencies)!
- πͺΆ **Lightweight** β Less than 50kb!
- π§ **Simple** β Just call a single function and boom π₯: instant ID!
- π **Secure** β Fresh, unique IDs every. single. time.
- π **CLI** β spin up IDs faster than you can blink!
## 𧬠Whatβs Under the Hood?
UCID runs independently [without any dependencies](https://www.npmjs.com/package/unique-custom-id?activeTab=dependencies) β just pure JavaScript magic β¨.
**If you use the default options, even if you generate 1 BILLION IDs PER SECOND, you'd need hundreds of millions of years to have a meaningful chance of a collision**. Sounds unbelievable? Letβs do the math:
### Collision Probability of Secure Random 32-Character ID (Base36)
**ID Format**: `xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx`
**Character Set**: 36 characters (`0β9`, `aβz`)
**Length**: 32 characters
**Randomness Source**: Cryptographically secure (`crypto.randomBytes`)
### Total Possible Unique IDs
36^32 β 6.334 Γ 10^49
### Generation Rate
- IDs per second: 1,000,000,000
- Seconds per year: 60 Γ 60 Γ 24 Γ 365 = 31,536,000
- IDs per year: 1 Γ 10^9 Γ 31,536,000 = 3.1536 Γ 10^16
### Collision Threshold (Birthday Paradox)
β(36^32) = 36^16 β 7.961 Γ 10^24
### Years to Reach 50% Collision Probability
7.961 Γ 10^24 Γ· 3.1536 Γ 10^16 β 252,443,706 years
### β
Conclusion
Using cryptographically secure randomness, your custom 32-character base36 ID format would take **~252 million years** of generating **1 BILLION IDs PER SECOND** to reach a **50% chance of collision**.
This makes it **EXTREMELY SAFE** for any real-world application. Offers **greater collision resistance than UUID v4** (~82 thousand years of generating 1 BILLION IDs PER SECOND) thanks to a larger entropy space (6.334 Γ 10^49), powered by cryptographically secure randomness.
## π οΈ How to Use It
### π¦ Installation
```sh
npm install unique-custom-id
```
### β Importing
ES Modules:
```js
import ucid from 'unique-custom-id';
```
CommonJS:
```js
const ucid = require('unique-custom-id');
```
### π Generate a Simple ID
```js
const id = ucid();
console.log(id);
// Result: dzcmj4dt-7zcqaoo0-t1mtis3v-3dh7r59v
```
## π§© Configuration Options
UCID isnβt just easy β itβs _flexible_ too! Customize your ID like a pro π οΈ
### `uppercase` and `lowercase` (booleans)
Control letter casing:
- `lowercase`: `true` by default
- `uppercase`: `false` by default
```js
ucid({
uppercase: true,
});
// Result: TevajtrU-Eei8SnWa-0EZqr6NE-jMAHX0D6
ucid({
uppercase: true,
lowercase: false,
});
// Result: FFJL9DAO-V3YPLZ2V-252L7URX-XCS3GWP5
```
### `numbers` and `symbols` (booleans)
Toggle digits or symbols:
- `numbers`: `true` by default
- `symbols`: `false` by default
```js
ucid({
symbols: true,
});
// Result: 5w55an#e-kw7bw7f3-7iomwp#o-dd79$yf1
ucid({
numbers: false,
});
// Result: jueldfjw-ljhiphtl-ajuptedx-rramdwne
```
### `octets` (number)
Set how many segments (octets) the ID should have. Default: `4`.
```js
ucid({
octets: 3,
});
// Result: 4nlwrx87-fi65iq27-43wh2s05
ucid({
octets: 6,
});
// Result: hr5bg68k-ycxqfb1o-pkofgsm2-j6hnimgy-ehcxulnl-ptmvuf3j
```
### `octetLength` (number)
Define how long each octet should be. Default: `8`.
```js
ucid({
octetLength: 4,
});
// Result: k6ue-bvfq-fc99-oe07
ucid({
octetLength: 12,
});
// Result: nz4kkg3jxxot-9v9bmx6y8ngt-x4ciymz48z9d-mqopg9mad4v2
```
### `includeOnly` (string)
Use a custom character set to generate your ID:
```js
ucid({
includeOnly: '1234567890abcdef',
});
// Result: f800cdb7-0082b1b8-f0736eb3-4b16949a
```
### `timestamp` (string)
Add timestamp to your ID. Either `prefix` or `suffix`.
- `prefix`: before the ID. Aliases: `prefix`, `p`, `pre`, `pref`
- `suffix`: after the ID. Aliases: `suffix`, `s`, `suf`, `suff`
```js
ucid({
timestamp: 'prefix', // `p`, `pre` or `pref` works too
});
// Result: 20250904-k0ebaf6m-j31g7koc-b25p0p2n-u9iah5i4
ucid({
timestamp: 'suff',
});
// Result: 05mdc0cp-6k6xvl9c-mgc7s9e3-t98ckh3f-20250904
```
### `timestampFormat` (string)
Controls how the timestamp is formatted.
You can use whatever format you like. yyyy-mm-dd, mm-dd-yy, however you like it, with additional predefined formats:
- unix / epoch
- military
- iso
- utc
- rfc (rfc3339)
- filetime / winft (Windows FILETIME)
```js
ucid({
octets: 3,
timestamp: 's',
timestampFormat: 'dd-mm-yyyy-hh:mm:ss:ms',
});
// Result: gtrf9t1h-u00ycxuw-mxzhjuty-04-09-2025-12:09:00:39
ucid({
octets: 3,
timestamp: 'p',
timestampFormat: 'unix',
});
// Result: 1756976740-61p0xk4r-1ad6fg3l-gxwsgpgk
```
### `octetSeparator` (string)
Customize the character(s) used to separate octets. Default: `"-"`
```js
ucid({ octetSeparator: '=' });
// Result: pro9mns=odvhrd3i=28e2mqzg=t3n530m9
ucid({ octetSeparator: '~' });
// Result: qm09extn~dy7s1bd1~t6fl9q2g~mv352ie4
```
### `octetFormat` (string | string[] | number | number[])
Set the **exact** length of each octet individually.
```js
ucid({
octets: 3,
octetFormat: '352',
});
// Result: h0c-hgkf0-k9
ucid({
octets: 4,
octetFormat: [2, 4, 6, 8],
});
// Result: cb-udw8-e6m4wt-i9kim7xb
ucid({
octets: 2,
octetFormat: 49,
});
// Result: pr3e-piis0fdy9
```
### `instances` (number)
Number of IDs to generate.
```js
ucid({
instances: 3,
});
/*
Result: [
'9v7z1v59-0v28lo6h-8g5qpnhk-dx5f6412',
'5689u3lw-ns4wk8sc-u57bgwxz-nm9r8ydf',
'ul7pdyya-bgubmkef-zlpp7b79-7v2oo5dq'
]
*/
ucid({
octets: 4,
octetFormat: [2, 4, 6, 8],
instances: 5,
});
/*
Result: [
'rd-c0ix-mtifus-z7ibcbip',
'l6-gngn-1v04eg-do2yei8v',
'kf-fprl-klp5bw-o7gcv39u',
'tm-v4hq-8h964i-cnpswp29',
'uq-iwcb-u44bey-yj0nvs98'
]
*/
```
### `template` (string | null)
- Use `%id` as a placeholder to inject generated IDs into custom strings.
- Use `%ts` as a placeholder to inject timestamp into custom strings.
```js
ucid({
octets: 1,
octetLength: 8,
includeOnly: '1234567890abcdef',
template: 'user-%id-session-%id',
});
// Result: user-1a97ada5-session-ec64776c
ucid({
octets: 1,
octetLength: 8,
includeOnly: '1234567890abcdef',
template: 'user-%id-at-%ts',
});
// Result: user-26001cde-at-20250903
```
### `prefix` and `suffix` (string)
Add static strings before or after your ID.
```js
ucid({
prefix: 'ID-',
suffix: '-done',
});
// Result: ID-k0ebaf6m-j31g7koc-b25p0p2n-u9iah5i4-done
```
### `verbose` (boolean)
Returns a full object instead of just the generated ID string.
If `verbose` is `true`, UCID will return an object containing the generated ID and other options that were passed in.
This is especially useful for logging, debugging, testing, or introspection. Default: `false`
```js
ucid({
octets: 3,
octetLength: 12,
includeOnly: '1234567890abcdef',
verbose: true,
});
/*
Result: {
ucid: '795ebe1fd531-dbf06d32bd02-f512ad09e84a',
octets: 3,
uppercase: false,
lowercase: true,
octetLength: 12,
octetFormat: '',
numbers: true,
octetSeparator: '-',
symbols: false,
includeOnly: '1234567890abcdef',
template: null,
prefix: '',
suffix: '',
verbose: true
}
*/
```
### `customize` (null | ((octet: string, index: number) => string))
Function to customize each octet further than other options.
```js
ucid({
octets: 2,
octetLength: 8,
includeOnly: '1234567890abcdef',
customize: (octet, i) => (i % 2 ? octet.toUpperCase() : octet.toLowerCase()),
});
// Result: 80a1a368-A738C260-32eaf5e3-3AF2803F
ucid({
octets: 3,
octetLength: 6,
includeOnly: '1234567890abcdef',
customize: (octet, i) =>
i == 0 ? `user-${octet}` : i == 1 ? `session-${octet}` : `${i}${octet}`,
});
// Result: user-81cd0a-session-13634d-212fb85
```
### `condition` (null | ((resolve: Function, reject: Function) => void))
Optional function that acts as a gate before UCID generation begins.
It must call `resolve()` to allow generation or `reject(msg)` to skip it.
If `reject()` is called, UCID generation is aborted, and the ucid function returns `undefined`.
If `reject()` is passed an `Error` object, it will be thrown. Otherwise, the error message is logged.
```js
// Allow generation only in production
ucid({
condition: (resolve, reject) =>
process.env.NODE_ENV === 'production'
? resolve()
: reject('UCID generation is disabled in non-production environments.'),
});
// Check authentication
ucid({
condition: (resolve, reject) =>
auth?.currentUser?.email
? resolve()
: reject(new Error('User must be authenticated.')),
});
```
## Predefined Formats
You don't have to memorize and write all those [configuration options](#-configuration-options). UCID contains predefined id formats like uuid, nanoid, cuid etc.
It uses the default configuration options in the back. For example:
```js
ucid.format('uuid');
// Result: afe5791b-788a-0c72-dc61-34b008e3fd98
```
On the back:
```js
ucid({
octets: 5,
octetFormat: [8, 4, 4, 4, 12],
includeOnly: '1234567890abcdef',
});
// Result: afe5791b-788a-0c72-dc61-34b008e3fd98
```
There are many predefined formats in UCID. Those predefined formats maybe existing or custom formats. Many of them have aliases.
- uuid / uuidv4 / universal / universal-id
- nano / nanoid / nano-id
- ksuid
- cuid
- ulid
- snowflake / snowflake-id
- sha / sha1
- sha256
- sha512
- md5
- object / objectid / object-id
- mongo / objectid24
- objectid32
- digits / numeric
- alphanumeric
- alpha
- ts-id / timestamp-id
- epoch-id
- jwt-id
- bcrypt-id
- argon-id
- host-id / machine-id
- session-id
- short
- mini
- ghost
- phantom
- ninja
- shortuuid / short-uuid / short-uuidv4
- hex / hexadecimal
```js
ucid.format('uuid'); // uuidv4, universal or universal-id also works
// Result: 368463db-db52-768a-499b-88e1b6698036
ucid.format('sha');
// Result: b216a7459df37c38b701ac2b5ad1ad5c634260f2
ucid.format('nanoid');
// Result: G3diDfj4Y4dZtjFxke9Js
ucid.format('cuid');
// Result: c25u32ul06423krgbcuygdpce
```
## π€ Want to Contribute?
We love contributions! π
If youβre thinking about improving [UCID](https://github.com/calebephrem/unique-custom-id), fixing a [bug](https://github.com/calebephrem/unique-custom-id/issues), or just having fun, make sure to read the [contributing guide](./CONTRIBUTING.md) before you start. Itβs got everything you need to know to get up and running! π
## π§Έ Final Thoughts
UCID is built for security, flexibility, and speed β perfect for devs who want secure and customizable identifiers in milliseconds.
## π Give It a Try!
```js
const magic = ucid();
console.log(`β¨ Your shiny new ID: ${magic}`);
```