TypeIDs are a modern, type-safe extension of UUIDv7. Inspired by a similar use of prefixes in Stripe's APIs.
TypeIDs are canonically encoded as lowercase strings consisting of three parts:
- A type prefix (at most 63 characters in all lowercase ASCII [a-z])
- An underscore '_' separator
- A 128-bit UUIDv7 encoded as a 26-character string using a modified base32 encoding.
Here's an example of a TypeID of type user
:
user_2x4y6z8a0b1c2d3e4f5g6h7j8k
└──┘ └────────────────────────┘
type uuid suffix (base32)
A formal specification defines the encoding in more detail.
- Type-safe: you can't accidentally use a
user
ID where apost
ID is expected. When debugging, you can immediately understand what type of entity a TypeID refers to thanks to the type prefix. - Compatible with UUIDs: TypeIDs are a superset of UUIDs. They are based on the upcoming UUIDv7 standard. If you decode the TypeID and remove the type information, you get a valid UUIDv7.
- K-Sortable: TypeIDs are K-sortable and can be used as the primary key in a database while ensuring good locality. Compare to entirely random global ids, like UUIDv4, that generally suffer from poor database locality.
- Thoughtful encoding: the base32 encoding is URL safe, case-insensitive, avoids ambiguous characters, can be selected for copy-pasting by double-clicking, and is a more compact encoding than the traditional hex encoding used by UUIDs (26 characters vs 36 characters).
Implementations should adhere to the formal specification.
Language | Status |
---|---|
Go | ✓ Implemented |
SQL | ✓ Implemented |
TypeScript | ✓ Implemented |
Language | Author | Validated Against Spec? |
---|---|---|
C# (.Net) | @TenCoKaciStromy | Yes, on 2023-06-30 |
C# (.Net Standard 2.1) | @cbuctok | Yes, on 2023-07-03 |
C# (.NET) | @firenero | Yes, on 2023-07-15 |
Dart | @mistermoe @tbd54566975 | Yes, on 2024-03-25 |
Elixir | @sloanelybutsurely | Yes, on 2023-07-02 |
Haskell | @MMZK1526 | Yes, on 2023-07-07 |
Java | @fxlae | Yes, on 2023-07-02 |
Java | @softprops | Yes, on 2023-07-04 |
OCaml | @titouancreach | Yes, on 2024-03-07 |
PHP | @BombenProdukt | Yes, on 2023-07-03 |
Python | @akhundMurad | Yes, on 2023-06-30 |
Ruby | @broothie | Yes, on 2023-06-30 |
Rust | @conradludgate | Yes, on 2023-07-01 |
Rust | @johnnynotsolucky | Yes, on 2023-07-13 |
Scala | @ant8e | Yes, on 2023-07-14 |
Scala | @guizmaii | Not yet |
Swift | @Frizlab | Yes, on 2023-07-07 |
T-SQL | @uniteeio | Yes, on 2023-08-25 |
TypeScript | @ongteckwu | Yes, on 2023-06-30 |
Zig | @tensorush | Yes, on 2023-07-05 |
We are looking for community contributions to implement TypeIDs in other languages.
This repo includes a command-line tool for generating TypeIDs. To install it, run:
curl -fsSL https://get.jetpack.io/typeid | bash
To generate a new TypeID, run:
$ typeid new prefix
prefix_01h2xcejqtf2nbrexx3vqjhp41
To decode an existing TypeID into a UUID run:
$ typeid decode prefix_01h2xcejqtf2nbrexx3vqjhp41
type: prefix
uuid: 0188bac7-4afa-78aa-bc3b-bd1eef28d881
And to encode an existing UUID into a TypeID run:
$ typeid encode prefix 0188bac7-4afa-78aa-bc3b-bd1eef28d881
prefix_01h2xcejqtf2nbrexx3vqjhp41
- UUIDv7 - The upcoming UUID standard that TypeIDs are based on.
Alternatives to UUIDv7 that are also worth considering (but not type-safe like TypeIDs):