npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@digicroz/ulid

v1.0.0

Published

TypeScript ULID library with monotonic generation, binary conversion, and validation - Universally Unique Lexicographically Sortable Identifiers for JavaScript and TypeScript projects

Downloads

96

Readme

@digicroz/ulid

TypeScript ULID library with monotonic generation and binary conversion - Universally Unique Lexicographically Sortable Identifiers for JavaScript and TypeScript projects.

npm version TypeScript MIT License Tree Shakable

A TypeScript library for generating and manipulating ULIDs (Universally Unique Lexicographically Sortable Identifiers).

🌐 Environment Compatibility

This library is designed to work across multiple JavaScript environments:

  • ✅ Node.js - Server-side applications
  • ✅ Browser - Client-side web applications
  • ✅ Web Workers - Background processing
  • ✅ React Native - Mobile applications

What is ULID?

ULID (Universally Unique Lexicographically Sortable Identifier) is a 128-bit identifier that is:

  • Sortable - Lexicographically sortable by time
  • Compact - 26 characters (vs 36 for UUID)
  • URL-safe - Uses Crockford's Base32 alphabet
  • Case-insensitive - No ambiguous characters
  • Monotonic - Guaranteed ordering within the same millisecond
  • Time-based - Encodes a timestamp in the first 48 bits

Features

  • 🚀 TypeScript Support - Full TypeScript support with type definitions
  • 📦 Tree Shakable - Import only what you need
  • 🔧 Monotonic Generation - Ensures IDs are always increasing
  • 💾 Binary Conversion - Lossless conversion between string and binary formats
  • Validation - Built-in ULID format validation
  • Time Decoding - Extract timestamps from ULIDs
  • 🌐 Cross-Platform - Works in Node.js, browsers, and web workers
  • 💡 Excellent IDE Support - Full auto-completion and IntelliSense support

Installation

npm install @digicroz/ulid

Alternative package managers:

# Yarn
yarn add @digicroz/ulid

# pnpm
pnpm add @digicroz/ulid

# Bun
bun add @digicroz/ulid

Quick Start

import { generateUlid, isValidUlid, decodeTimeFromUlid } from "@digicroz/ulid";

// Generate a new ULID
const id = generateUlid();
console.log(id); // "01JCQX5YQHJ8Z9KQXH5YQHJ8Z0"

// Validate ULID format
const isValid = isValidUlid(id);
console.log(isValid); // true

// Decode timestamp from ULID
const timestamp = decodeTimeFromUlid(id);
console.log(new Date(timestamp)); // Current date/time

API Reference

Core Functions

generateUlid(seedTime?: number): string

Generates a new ULID with monotonic guarantees.

import { generateUlid } from "@digicroz/ulid";

// Generate with current time
const id1 = generateUlid();

// Generate with specific timestamp
const id2 = generateUlid(Date.now());

Features:

  • Monotonic mode ensures IDs are always increasing
  • Last character is always '0' for perfect 128-bit binary conversion
  • Handles clock drift gracefully

isValidUlid(id: string): boolean

Validates if a string is a valid ULID format.

import { isValidUlid } from "@digicroz/ulid";

isValidUlid("01JCQX5YQHJ8Z9KQXH5YQHJ8Z0"); // true
isValidUlid("invalid"); // false
isValidUlid("01JCQX5YQHJ8Z9KQXH5YQHJ8ZI"); // false (invalid character 'I')

Validation checks:

  • Exactly 26 characters
  • All characters are valid Crockford Base32 (0-9, A-Z excluding I, L, O, U)
  • Case-insensitive

decodeTimeFromUlid(id: string): number

Extracts the timestamp from a ULID.

import { decodeTimeFromUlid } from "@digicroz/ulid";

const id = "01JCQX5YQHJ8Z9KQXH5YQHJ8Z0";
const timestamp = decodeTimeFromUlid(id);
console.log(new Date(timestamp)); // Date when the ULID was created

// Throws error if invalid ULID
try {
  decodeTimeFromUlid("invalid");
} catch (error) {
  console.error("Invalid ULID format");
}

getUlidAge(id: string): number

Returns the age of a ULID in milliseconds.

import { getUlidAge } from "@digicroz/ulid";

const id = generateUlid();
// ... some time passes ...
const age = getUlidAge(id);
console.log(`ULID is ${age}ms old`);

parseUlid(id: string): object

Parses a ULID and extracts all its components.

import { parseUlid } from "@digicroz/ulid";

const id = "01JCQX5YQHJ8Z9KQXH5YQHJ8Z0";
const parsed = parseUlid(id);

console.log(parsed);
// {
//   timestamp: 1699891200000,          // milliseconds since epoch
//   timestampSeconds: 1699891200,      // seconds since epoch
//   age: 1234                          // milliseconds since creation
// }

Binary Conversion Functions

ulidToBinary(id: string): Uint8Array

Converts a ULID string to 16-byte binary format for efficient storage.

import { ulidToBinary } from "@digicroz/ulid";

const id = "01JCQX5YQHJ8Z9KQXH5YQHJ8Z0";
const binary = ulidToBinary(id);
console.log(binary); // Uint8Array(16) [...]
console.log(binary.length); // 16 bytes (128 bits)

Benefits:

  • Lossless conversion (100% reversible)
  • Saves space in databases (16 bytes vs 26 characters)
  • Perfect for binary storage formats

binaryToUlid(bytes: Uint8Array | Buffer): string

Converts 16-byte binary format back to ULID string.

import { binaryToUlid, ulidToBinary } from "@digicroz/ulid";

const id = "01JCQX5YQHJ8Z9KQXH5YQHJ8Z0";
const binary = ulidToBinary(id);
const restored = binaryToUlid(binary);

console.log(id === restored); // true (lossless conversion)

Features:

  • Works with both Uint8Array and Node.js Buffer
  • Maintains consistency with generated ULIDs (last char is '0')

Usage Examples

Database Storage

Store ULIDs efficiently in binary format:

import { generateUlid, ulidToBinary, binaryToUlid } from "@digicroz/ulid";

// Generate ULID
const userId = generateUlid();

// Store in database as binary (saves space)
const binaryId = ulidToBinary(userId);
await db.users.insert({ id: binaryId, name: "John" });

// Retrieve and convert back
const user = await db.users.findOne({ id: binaryId });
const readableId = binaryToUlid(user.id);
console.log(readableId); // Original ULID string

Sorting by Creation Time

ULIDs are naturally sortable by creation time:

import { generateUlid } from "@digicroz/ulid";

const ids = [];
ids.push(generateUlid());
await sleep(10);
ids.push(generateUlid());
await sleep(10);
ids.push(generateUlid());

// Sort naturally
ids.sort();
// IDs are now in chronological order!

URL-safe Identifiers

Use ULIDs in URLs without encoding:

import { generateUlid } from "@digicroz/ulid";

const articleId = generateUlid();
const url = `https://example.com/articles/${articleId}`;
// No URL encoding needed!

Distributed Systems

ULIDs work great in distributed systems:

import { generateUlid } from "@digicroz/ulid";

// Each server can generate unique IDs independently
// Server 1
const serverId1 = generateUlid();

// Server 2 (at the same time)
const serverId2 = generateUlid();

// IDs are guaranteed unique and sortable across servers

TypeScript Configuration

For optimal compatibility, ensure your tsconfig.json uses modern module resolution:

{
  "compilerOptions": {
    "moduleResolution": "bundler", // or "node16"/"nodenext"
    "module": "ESNext",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "skipLibCheck": true
  }
}

ULID Specification

This library implements the ULID specification:

 01AN4Z07BY      79KA1307SR9X4MV3

|----------|    |----------------|
 Timestamp          Randomness
   48bits             80bits
  • Timestamp: 48-bit integer (millisecond precision)
  • Randomness: 80-bit random number
  • Encoding: Crockford's Base32 (case-insensitive)
  • Length: 26 characters
  • Sortable: Lexicographically by time

Character Set

Uses Crockford's Base32 for better readability:

0123456789ABCDEFGHJKMNPQRSTVWXYZ

Excluded characters: I, L, O, U (to avoid confusion)

Comparison with UUID

| Feature | ULID | UUID v4 | | ------------------------ | ---------------- | ---------------------------- | | Length | 26 characters | 36 characters (with hyphens) | | Sortable | ✅ Yes (by time) | ❌ No | | Monotonic | ✅ Yes | ❌ No | | URL-safe | ✅ Yes | ⚠️ Needs encoding | | Case-sensitive | ❌ No | ✅ Yes | | Timestamp | ✅ Embedded | ❌ No | | Collision Resistance | ✅ High | ✅ High | | Binary Size | 128 bits | 128 bits |

Performance

  • Generation: ~100,000 IDs per second (monotonic mode)
  • Validation: ~1,000,000 validations per second
  • Binary Conversion: ~500,000 conversions per second

Browser Support

Works in all modern browsers:

  • Chrome/Edge (latest)
  • Firefox (latest)
  • Safari (latest)
  • React Native
  • Web Workers

Node.js Support

Requires Node.js 16.0.0 or higher.

Development

# Install dependencies
npm install

# Build the project
npm run build

# Watch mode for development
npm run dev

# Clean build artifacts
npm run clean

License

MIT © Adarsh Hatkar

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Related Projects

  • ulid/spec - ULID specification
  • ulidx - Core ULID library used internally

Support

For issues and feature requests, please use the GitHub issue tracker.