typeid-js

Type-safe, K-sortable, globally unique identifiers for TypeScript, based on UUIDv7.

Library
npm
v1.2.0
436stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
43/100Fair
Development Activity28
Maintenance4
Community48
Maturity52
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
78/100Good
Architecture82
Code Quality80
Innovation85
Learning Curve65

typeid-js is the official TypeScript/JavaScript implementation of the TypeID specification, a modern identifier format that pairs a human-readable type prefix (like user_ or order_) with a UUIDv7-based suffix encoded in Crockford base32. The result is an identifier that is globally unique, lexicographically sortable by creation time, and type-safe when compiled with TypeScript generics, so a function expecting a TypeID<'user'> cannot accidentally be passed an order ID.

Under the hood, the library generates suffixes from UUIDv7 using the same uuid package that powers most of the JavaScript ecosystem, then encodes them into a fixed 26-character base32 string free of ambiguous characters. It exposes both a class-based API (TypeID, typeid()) for ergonomic construction and parsing, and an unboxed, allocation-light functional API (typeidUnboxed, fromString, getType, getSuffix) for callers who want to avoid the object wrapper, plus round-trip conversion to and from standard UUID strings and byte arrays.

What You Get

  • A class-based TypeID/typeid() API with TypeScript generic type-checking on the prefix
  • An unboxed, allocation-light functional API (typeidUnboxed, fromString, getType, getSuffix) documented in its own README under src/unboxed/
  • UUID interoperability helpers (fromUUID, toUUID, fromUUIDBytes, toUUIDBytes) for migrating existing UUID-keyed data
  • Dedicated typed error classes for every validation failure mode (invalid prefix, invalid suffix length/character, prefix mismatch)
  • Dual ESM/CJS build output with bundled .d.ts declarations via tsup

Common Use Cases

  • Using TypeIDs as human-readable, type-checked primary keys in a database
  • Passing type-tagged identifiers between services in a TypeScript codebase so a compile-time check catches a mismatched entity ID
  • Generating K-sortable IDs across distributed systems without a central sequence generator
  • Migrating existing UUID-keyed data to TypeIDs incrementally while retaining UUID wire compatibility

Under The Hood

Architecture The library is a flat, single-purpose module tree under src/: typeid.ts (the class-based public API) wraps src/unboxed/typeid.ts (a pure functional core), which itself composes three small independent modules — parse_uuid.ts (hex string to byte array), base32.ts (byte array to/from a 26-character Crockford base32 string via manual bit-shifting), and prefix.ts (prefix character validation). The TypeID class delegates all encoding/validation logic to the unboxed layer (typeidUnboxed, fromString, getType, getSuffix) and only adds object-oriented ergonomics — constructor, asType, toString — on top, so the real entry point for behavior changes is src/unboxed/typeid.ts. index.ts is a pure re-export barrel with no logic of its own. There is no I/O, no async, and no dependency injection: the whole system is synchronous pure functions over byte arrays and strings, so changing the 16-byte UUID layout assumption in parse_uuid.ts/base32.ts would ripple through every encode/decode call site.

Tech Stack Written in TypeScript targeting an ES2019 lib, built with tsup for dual ESM+CJS output plus bundled .d.ts declarations, and shipped with sideEffects: false for tree-shaking. The only runtime dependency is the uuid package (for UUIDv7 generation and stringification); everything else — base32 encoding, prefix validation, error types — is hand-written with no additional runtime dependencies. Tests run through Jest with ts-jest; formatting is handled by Prettier. A devbox.json/devbox.lock pair (Jetify’s own reproducible-environment tool) pins the local dev toolchain.

Code Quality The test suite is extensive relative to the library’s size: constructor validation, asType narrowing, toString/fromString round-trips, fromUUID/fromUUIDBytes conversions, a 1000-iteration randomized encode-decode invariant check, and spec-conformance tests run against the official TypeID spec’s valid/invalid test-vector fixtures. Error handling is explicit and typed throughout, with a dedicated Error subclass per failure mode rather than generic throws or swallowed errors, and TypeScript’s strictest settings are enabled via the @tsconfig/strictest dev dependency. No CI workflow file is present in this specific repository — it is a read-only mirror auto-published from Jetify’s internal monorepo, where its CI most likely lives — so build/test automation for this exact copy could not be directly confirmed.

API Design The dual class-based and unboxed functional APIs let consumers choose object ergonomics or a zero-allocation, string-based approach, with the unboxed variant documented separately. TypeScript’s const T extends string generic parameters give literal-type inference on prefixes with no manual annotations, so typeid('user') is automatically typed as TypeID<'user'>. Getting started requires one import and one function call, with sensible defaults — no prefix, auto-generated suffix — provided through overloaded function signatures, and naming (fromUUID, toUUID, fromString, toString) follows conventions already familiar to anyone who has used the uuid package.

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