TypeID: a K-sortable, type-prefixed identifier you can adopt from the command line
Type-safe, K-sortable, globally unique identifier inspired by Stripe IDs
At a glance
- What is it?
- jetify-com/typeid is the Go CLI for TypeIDs, a UUIDv7-based identifier format with a lowercase type prefix. It is useful when you want sortable primary keys that tell you what entity they point at, and the repository also holds the formal specification other language ports follow.
- Who is it for?
- Adopt TypeID if you want database keys that sort by creation time and carry a readable type prefix, and you are willing to depend on a v2 module that is still published as an alpha. Do not adopt it if you need a stable, tagged release line today, or if your tooling cannot accept a 128-bit UUIDv7 payload behind a prefix.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 74 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem TypeID solves for application developers
Random identifiers such as UUIDv4 give you uniqueness and nothing else. They scatter across a B-tree index, so inserts land in unrelated pages, and nothing in the string tells a human which table the value came from. TypeID attacks both problems at once. The README describes it as a "type-safe, K-sortable, globally unique identifier inspired by Stripe IDs", and the type prefix is the part borrowed from Stripe: a `user` ID and a `post` ID are visibly different strings, so a copy-paste mistake or a mismatched argument is easier to catch.
The intended audience is anyone who stores identifiers as primary keys and also reads them by eye: backend engineers debugging logs, support staff pasting an ID into a query, and API designers who want self-describing resources. It is not aimed at systems that need opaque tokens, because the prefix leaks the entity type by design.
How the TypeID encoding works: prefix, separator, base32 UUIDv7
A TypeID has exactly three parts. First a type prefix of at most 63 characters, lowercase snake_case ASCII limited to `[a-z_]`. Then a single underscore separator. Then a 128-bit UUIDv7 rendered as a 26-character string using a modified base32 alphabet. The README gives this example for a `user`:
user_2x4y6z8a0b1c2d3e4f5g6h7j8k
└──┘ └────────────────────────┘
type uuid suffix (base32)Because the payload is UUIDv7, the high bits are a millisecond timestamp, which is what makes the values K-sortable: sorting the strings sorts them roughly by creation time, and a database index therefore gets good locality on insert. Strip the prefix and decode the suffix and you have a valid UUIDv7, so the format is a superset rather than a replacement. The base32 encoding is 26 characters against the 36 of hex, and the README notes it is URL safe, case-insensitive, avoids ambiguous characters, and can be selected by double-clicking.
The formal definition lives in the `spec/` directory of this repository, and the README states the latest spec version is v0.3.0. That matters more than it first appears: this repository is the reference, and the language implementations are expected to follow it.
Installing the TypeID CLI and generating your first ID
The repository is a Go module named `go.jetify.com/typeid-cli`, and the entry point is `main.go` at the top level, with the command definitions under `cli/`. The README does not include an install section, so the route the repository layout supports is the Go toolchain against the module path recorded in `go.mod`. The `require` block of that file gives the module line to install from and the library it pulls in:
go.jetify.com/typeid-cli
go.jetify.com/typeid/v2 v2.0.0-alpha.3That dependency is worth reading closely. `go.mod` pins `go.jetify.com/typeid/v2` at `v2.0.0-alpha.3`, an alpha, while the repository's own tagged releases stop at v0.1.1 from 2023-07-01. So a build taken from the current tree sits on a v2 module line that has not been tagged stable, even though the repository's last push was on 2026-07-17. Treat the CLI as tracking the specification rather than as a frozen release artifact.
The README documents no subcommands or flags for the CLI, so check the binary's own help output before scripting against it. For a first real use, the README points at Jetify's online converter at jetify.com/typeid: paste a TypeID to get the UUID, or supply `prefix:UUID` to get a TypeID back. That round trip is the fastest way to confirm the encoding behaves as the spec describes before you wire it into a schema.
Where TypeID is the wrong choice
The prefix is the feature and also the constraint. If an identifier appears in a URL that should not reveal what it points at, or in a context where an attacker enumerating one prefix tells you something useful, TypeID is working against you. Opaque random tokens exist for that reason.
The 63-character prefix limit is generous but real, and the README does not describe any canonicalisation step for prefixes that violate the snake_case rule, so validation is on you. Uniqueness is inherited from UUIDv7, which is not a guarantee of collision-freedom in the mathematical sense, only an extremely low probability; the README does not discuss collision handling.
The bigger practical issue is release discipline. The CLI depends on `v2.0.0-alpha.3`. If your organisation requires pinned, non-prerelease dependencies, the module line does not currently satisfy that, and the README does not document a rollback or migration path between spec versions. The README also does not document how the CLI handles malformed input such as an uppercase prefix or a suffix of the wrong length, so you cannot assume it fails loudly.
TypeID compared with raw UUIDv7 and with prefixed UUIDs you build yourself
The nearest alternative is a plain UUIDv7 with no prefix. You keep the time-ordered property and the same 128-bit payload, and you avoid a dependency entirely, because UUIDv7 generation is available in many standard libraries. What you lose is the type information: a UUIDv7 in a log line tells you nothing about which entity it identifies, and the hex form is 36 characters rather than 26.
The other alternative is a homegrown convention, for example storing `user` in a separate column or prefixing a UUID with a string in application code. That works until two services disagree about the separator, the case, or the alphabet. TypeID's value is that the format is written down in `spec/` and implemented across many languages, so a Go service and a TypeScript service can exchange the same string with the same meaning. The README lists official implementations for Go, SQL and TypeScript at spec v0.3, and a long table of community ports in C#, Dart, Elixir, Erlang, Gleam, Haskell, Java, Kotlin and Lua. Several of those community entries are still recorded at v0.2 or v0.1, which is the real cost of a spec-first format: the ecosystem moves at different speeds.
Maintenance, licensing and the cost of tracking the spec
The repository is not archived, and its last push was on 2026-07-17. The tagged releases are old by comparison: v0.1.1 dates from 2023-07-01 and v0.1.0 from 2023-06-27. So the code has moved since the last tag without a corresponding release, and the CLI's alpha dependency suggests the maintainers are still iterating on the v2 module. Plan for the possibility that upgrading means reading the spec diff rather than a changelog, since the README does not point at one.
The licence is Apache-2.0, declared in the repository's `LICENSE` file and in the README badge. Apache-2.0 is permissive and includes an explicit patent grant, which is friendlier than MIT for adopters who care about that clause. The usual obligations apply: keep the licence and notices with redistributed copies, and note that the licence covers the specification text and the implementations in this repository, not the separately hosted ports, which carry their own terms. That is a factual observation about repository layout, not legal advice; check the terms of any port you actually use.
Upgrade cost is dominated by the specification version rather than by the code. If you adopt TypeID at spec v0.3 and a future spec revision changes the alphabet or the prefix rules, every stored identifier is affected, and the README does not describe a compatibility strategy for that case.
Editorial conclusion
Adopt TypeID if you want database keys that sort by creation time and carry a readable type prefix, and you are willing to depend on a v2 module that is still published as an alpha. Do not adopt it if you need a stable, tagged release line today, or if your tooling cannot accept a 128-bit UUIDv7 payload behind a prefix. Before committing, verify three things yourself: that the Go module version go.jetify.com/typeid/v2 resolves from your proxy, that your database column is wide enough for the full prefixed string, and that your chosen language has an implementation at spec v0.3, since the README lists several ports still pinned to v0.2 or v0.1.
Frequently asked questions
What is a TypeID?
A TypeID is a type-safe, K-sortable, globally unique identifier inspired by Stripe IDs. It is a type prefix, an underscore separator, and a 128-bit UUIDv7 encoded as a 26-character base32 string.
How do I install the TypeID CLI?
The README does not include an install section. The repository is a Go module named go.jetify.com/typeid-cli, so the Go toolchain route is go install go.jetify.com/typeid-cli@latest, which pulls in the go.jetify.com/typeid/v2 library listed in go.mod.
Is a TypeID compatible with a UUID?
Yes. The README states that TypeIDs are a superset of UUIDs and are based on UUIDv7, so if you decode the TypeID and remove the type information you get a valid UUIDv7.
What is the difference between a TypeID and a plain UUIDv7?
Both carry the same 128-bit UUIDv7 payload, so both are time-ordered. TypeID adds a lowercase snake_case type prefix and encodes the payload in 26 base32 characters instead of 36 hex characters, which makes the entity type visible in the string.
Which languages have a TypeID implementation?
The README lists official implementations by Jetify for Go, SQL and TypeScript at spec v0.3, plus community ports in C#, Dart, Elixir, Erlang, Gleam, Haskell, Java, Kotlin and Lua. Several community ports are recorded at spec v0.2 or v0.1 rather than v0.3.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/jetify-com-typeid)