typeid-js
Type-safe, K-sortable, globally unique identifiers for TypeScript, based on UUIDv7.
Repository Health
Technical Analysis
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 undersrc/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.tsdeclarations 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.
Used by 2 apps in this directory
Mistle
AI Agents · Developer Tools
Self-hostable platform for running autonomous coding agents in isolated, credentialless sandboxes with brokered credentials, reusable snapshots, and event-driven triggers.
openwork
AI Assistants · Automation
OpenWork is a free, open-source desktop app for running AI agent workflows on your own files with 50+ LLMs, extensible skills, and MCP server support — the open-source alternative to Claude Cowork and Codex.