MCPcopy
hub / github.com/paralleldrive/cuid2

github.com/paralleldrive/cuid2 @v3.3.0 sqlite

repository ↗ · DeepWiki ↗ · release v3.3.0 ↗
59 symbols 122 edges 18 files 0 documented · 0%
README

Cuid2

aidd FrameworkParallel Drive

Secure, collision-resistant ids optimized for horizontal scaling and performance. Next generation UUIDs.

Need unique ids in your app? Forget UUIDs and GUIDs which often collide in large apps. Use Cuid2, instead.

Cuid2 is:

  • Secure: It's not feasible to guess the next id, existing valid ids, or learn anything about the referenced data from the id. Cuid2 uses multiple, independent entropy sources and hashes them with a security-audited, NIST-standard cryptographically secure hashing algorithm (Sha3).
  • Collision resistant: It's extremely unlikely to generate the same id twice (by default, you'd need to generate roughly 4,000,000,000,000,000,000 ids (sqrt(36^(24-1) * 26) = 4.0268498e+18) to reach 50% chance of collision.)
  • Horizontally scalable: Generate ids on multiple machines without coordination.
  • Offline-compatible: Generate ids without a network connection.
  • URL and name-friendly: No special characters.
  • Fast and convenient: No async operations. Won't introduce user-noticeable delays. Less than 5k, gzipped.
  • But not too fast: If you can hash too quickly you can launch parallel attacks to find duplicates or break entropy-hiding. For unique ids, the fastest runner loses the security race.

Cuid2 is not good for:

  • Sequential ids (see the note on k-sortable ids, below)
  • High performance tight loops, such as render loops (if you don't need cross-host unique ids or security, consider a simple counter for this use-case, or try Ulid or NanoId).

Getting Started

npm install --save @paralleldrive/cuid2

Or

yarn add @paralleldrive/cuid2

CLI Usage

First, install the shell alias for easier access:

# Install shell alias (recommended)
npx @paralleldrive/cuid2 --install
# ✓ Alias added to .zshrc
# Run: source ~/.zshrc

# View all CLI options
npx @paralleldrive/cuid2 --help

Now generate IDs from the command line:

# Generate a single ID
cuid
# tz4a98xxat96iws9zmbrgj3a

# Generate multiple IDs
cuid 5
# pfh0haxfpzowht3oi213cqos
# nc6bzmkmd014706rfda898to
# ...

# Generate a short slug (5 characters)
cuid --slug
# ra3f3

# Generate multiple slugs
cuid --slug 3
# cgejt
# howzq
# sd67n

# Custom length
cuid --length 10
# c94jt94rt4

# Custom fingerprint
cuid --fingerprint "my-server" 2
# mv8nuzaehk1l9pww1wlmzqax
# n04n62wsow10n3l4huidgkle

# Combine options
cuid --length 8 --fingerprint "test"
# ysk16xlf

# Without alias, use the full command
npx @paralleldrive/cuid2

CLI Options

cuid2 [count] [options]

Arguments:
  count              Number of IDs to generate (default: 1)

Options:
  --slug             Generate a short 5-character ID
  --length <n>       Custom ID length (default: 24)
  --fingerprint <s>  Custom fingerprint for ID generation
  --install          Install shell alias 'cuid' → 'npx @paralleldrive/cuid2'
  --help, -h         Show help message

Programmatic Usage

import { createId } from "@paralleldrive/cuid2";

const ids = [
  createId(), // 'tz4a98xxat96iws9zmbrgj3a'
  createId(), // 'pfh0haxfpzowht3oi213cqos'
  createId(), // 'nc6bzmkmd014706rfda898to'
];

Using Jest? Jump to Using with Jest.

Configuration

import { init } from "@paralleldrive/cuid2";

// The init function returns a custom createId function with the specified
// configuration. All configuration properties are optional.
const createId = init({
  // A custom random function with the same API as Math.random.
  // You can use this to pass a cryptographically secure random function.
  random: Math.random,
  // the length of the id
  length: 10,
  // A custom fingerprint for the host environment. This is used to help
  // prevent collisions when generating ids in a distributed system.
  fingerprint: "a-custom-host-fingerprint",
});

console.log(
  createId(), // wjfazn7qnd
  createId(), // cerhuy9499
  createId() // itp2u4ozr4
);

Validation

import { createId, isCuid } from "@paralleldrive/cuid2";

console.log(
  isCuid(createId()), // true
  isCuid("not a cuid") // false
);

Trusted by Millions of Apps

Cuid2 is trusted by millions of apps and attracts ~6.5 million weekly downloads.

Why Cuid2?

Ids should be secure by default for the same reason that browser sessions should be secure by default. There are too many things that can go wrong when they're not, and insecure ids can cause problems in unexpected ways, including unauthorized user account access, unauthorized access to user data, and accidental leaks of user's personal data which can lead to catastrophic effects, even in innocent-sounding applications like fitness run trackers (see the 2018 Strava Pentagon breach and PleaseRobMe).

Not all security measures should be considered equal. For example, it's not a good idea to trust your browser's "Cryptographically Secure" Pseudo Random Number Generator (CSPRNG) (used in tools like uuid and nanoid). For example, there may be bugs in browser CSPRNGs. For many years, Chromium's Math.random() wasn't very random at all. Cuid was created to solve the issue of untrustworthy entropy in id generators that led to frequent id collisions and related problems in production applications. Instead of trusting a single source of entropy, Cuid2 combines several sources of entropy to provide stronger security and collision-resistance guarantees than are available in other solutions.

Modern web applications have different requirements than applications written in the early days of GUID (globally unique identifiers) and UUIDs (universally unique identifiers). In particular, Cuid2 aims to provide stronger uniqueness guarantees than any existing GUID or UUID implementation and protect against leaking any information about the data being referenced, or the system that generated the id.

Cuid2 is the next generation of Cuid, which has been used in thousands of applications for over a decade with no confirmed collision reports. The changes in Cuid2 are significant and could potentially disrupt the many projects that rely on Cuid, so we decided to create a replacement library and id standard, instead. Cuid is now deprecated in favor of Cuid2.

Entropy is a measure of the total information in a system. In the context of unique ids, a higher entropy will lead to fewer collisions, and can also make it more difficult for an attacker to guess a valid id.

Cuid2 is made up of the following entropy sources:

  • An initial letter to make the id a usable identifier in JavaScript and HTML/CSS
  • The current system time
  • Pseudorandom values
  • A session counter
  • A host fingerprint

The string is Base36 encoded, which means it contains only lowercase letters and the numbers: 0 - 9, with no special symbols.

Horizontal scalability

Today's applications don't run on any single machine.

Applications might need to support online / offline capability, which means we need a way for clients on different hosts to generate ids that won't collide with ids generated by other hosts -- even if they're not connected to the network.

Most pseudo-random algorithms use time in ms as a random seed. Random IDs lack sufficient entropy when running in separate processes (such as cloned virtual machines or client browsers) to guarantee against collisions. Application developers report v4 UUID collisions causing problems in their applications when the ID generation is distributed between lots of machines such that lots of IDs are generated in the same millisecond.

Each new client exponentially increases the chance of collision in the same way that each new character in a random string exponentially reduces the chance of collision. Successful apps scale at hundreds or thousands of new clients per day, so fighting the lack of entropy by adding random characters is a recipe for ridiculously long identifiers.

Because of the nature of this problem, it's possible to build an app from the ground up and scale it to a million users before this problem is detected. By the time you notice the problem (when your peak hour use requires dozens of ids to be created per ms), if your db doesn't have unique constraints on the id because you thought your guids were safe, you're in a world of hurt. Your users start to see data that doesn't belong to them because the db just returns the first ID match it finds.

Alternatively, you've played it safe and you only let your database create ids. Writes only happen on a master database, and load is spread out over read replicas. But with this kind of strain, you have to start scaling your database writes horizontally, too, and suddenly your application starts to crawl (if the db is smart enough to guarantee unique ids between write hosts), or you start getting id collisions between different db hosts, so your write hosts don't agree about which ids represent which data.

Performance

Id generation should be fast enough that humans won't notice a delay, but too slow to feasibly brute force (even in parallel). That means no waiting around for asynchronous entropy pool requests, or cross-process/cross-network communication. Performance slows to impracticality in the browser. All sources of entropy need to be fast enough for synchronous access.

Even worse, when the database is the only guarantee that ids are unique, that means that clients are forced to send incomplete records to the database, and wait for a network round-trip before they can use the ids in any algorithm. Forget about fast client performance. It simply isn't possible.

That situation has caused some clients to create ids that are only usable in a single client session (such as an in-memory counter). When the database returns the real id, the client has to do some juggling logic to swap out the id being used, adding complexity to the client implementation code.

If client side ID generation were stronger, the chances of collision would be much smaller, and the client could send complete records to the db for insertion without waiting for a full round-trip request to finish before using the ID.

Tiny

Page loads need to be FAST, and that means we can't waste a lot of JavaScript on a complex algorithm. Cuid2 is tiny. This is especially important for thick-client JavaScript applications.

Secure

Client-visible ids often need to have sufficient random data and entropy to make it practically impossible to try to guess valid IDs based on an existing, known id. That makes simple sequential ids unusable in the context of client-side generated database keys. Additionally, using V4 UUIDs is also not safe, because there are known attacks on several id generating algorithms that a sophisticated attacker can use to predict next ids. Cuid2 has been audited by security experts and artificial intelligence, and is considered safe to use for use-cases like secret sharing links.

Portable

Most stronger forms of the UUID / GUID algorithms require access to OS services that are not available in browsers, meaning that they are impossible to implement as specified. Further, our id standard needs to be portable to many languages (the original cuid has 22 different language implementations).

Ports

Improvements Over Cuid

The original Cuid served us well for more than a decade. We used it across 2 different social networks, and to generate ids for Adobe Creative Cloud. We never had a problem with collisions in production systems using it. But there was room for improvement.

Better Collision Resistance

Available entropy is the maximum number of unique ids that can be generated. Generally more entropy leads to lower probability of collision. For simplicity, we will assume a perfectly random distribution in the following discussion.

The original Cuid ran for more than 10 years in across thousands of software implementations with zero confirmed collision reports, in some cases with more than 100 mill

Core symbols most depended-on inside this repo

info
called by 29
src/test-utils.js
isCuid
called by 18
src/index.js
runCli
called by 11
src/bin-test.js
init
called by 7
src/index.js
createEntropy
called by 3
src/index.js
bufToBigInt
called by 3
src/index.js
createFingerprint
called by 3
src/index.js
hash
called by 2
src/index.js

Shape

Function 59

Languages

TypeScript100%

Modules by API surface

src/pages/design-system.js16 symbols
design-system.js13 symbols
src/index.js11 symbols
release.js7 symbols
src/test-utils.js4 symbols
src/collision-test.js2 symbols
pages/randogram.js2 symbols
src/index-test.js1 symbols
src/bin-test.js1 symbols
pages/_app.js1 symbols
bin/cuid2.js1 symbols

Dependencies from manifests, versioned

@noble/hashes2.0.1 · 1×
@types/node25.0.10 · 1×
@types/react19.2.9 · 1×
aidd2.5.0 · 1×
bignumber.js9.3.1 · 1×
error-causes3.0.2 · 1×
eslint9.39.2 · 1×
eslint-config-next16.1.4 · 1×
eslint-config-prettier10.1.8 · 1×
eslint-plugin-prettier5.5.5 · 1×
husky9.0.11 · 1×
next16.1.4 · 1×

For agents

$ claude mcp add cuid2 \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact