ulid-rs

A Rust implementation of ULID — Universally Unique Lexicographically Sortable Identifiers

Library
Cargo
v3.0.0
474stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
56/100Fair
Development Activity56
Maintenance32
Community56
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
76/100Good
Architecture74
Code Quality76
Innovation66
Learning Curve88

ulid-rs implements the ULID specification in Rust: 128-bit identifiers that are lexicographically sortable by creation time, encode as a compact 26-character string, and remain collision-resistant like a UUID. Ulid::generate() produces monotonic-friendly IDs suitable for database primary keys, event ordering, and distributed ID generation without a central coordinator.

The crate supports no_std environments, optional serde serialization (either as the canonical string form or as the underlying u128), and optional integrations with postgres-types, uuid, and rkyv, making it easy to drop ULIDs into existing Rust data models and database schemas.

What You Get

  • Ulid::generate() and Ulid::from_string() for creating and parsing 26-character ULIDs
  • Lexicographic sortability by creation timestamp, unlike random UUIDs
  • Optional no_std support for embedded or constrained environments
  • serde serialization as either the canonical string or the inner u128
  • Optional interop with postgres-types, the uuid crate, and rkyv zero-copy serialization

Common Use Cases

  • Generating sortable primary keys for database rows without a central auto-increment sequence
  • Ordering distributed events or log entries by embedded creation timestamp
  • Replacing random UUIDs where index locality and sort order matter for performance
  • Serializing IDs directly into Postgres columns via the optional postgres feature

Under The Hood

Architecture - The crate’s core type is defined in lib.rs, storing a ULID as a single u128 combining a 48-bit timestamp with 80 bits of randomness; generator.rs implements a Generator that can produce monotonically increasing ULIDs within the same millisecond by incrementing the randomness component, while base32.rs handles the Crockford base32 encoding/decoding used for the canonical 26-character string representation.

Tech Stack - A small, dependency-light Rust crate (~1,500 lines, edition 2018) with all major dependencies gated behind Cargo features: rand for std generation, serde for serialization, postgres-types/bytes for Postgres interop, uuid for conversion, and rkyv for zero-copy deserialization — letting consumers pull in only what they need.

Code Quality - Tests are colocated in a tests/ directory plus inline unit tests, with lints.rust.keyword_idents = "warn" configured in Cargo.toml showing attention to lint hygiene; a separate cli/ subdirectory provides a small companion command-line tool for generating/inspecting ULIDs, kept out of the main library crate to avoid pulling CLI dependencies into library consumers.

API Design - The API is intentionally minimal — Ulid::generate(), Ulid::from_string(), Ulid::to_string() — mirroring the ergonomics of the widely-used uuid crate closely enough that switching between the two requires little relearning, while feature flags (rather than always-on dependencies) keep the default build small for users who don’t need Postgres or rkyv integration.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search