user.Br2flcNDfF6LYICnT
Human-readable. Use in logs, URLs, APIs, and anywhere humans might see it.
A TNID (Typed Named ID) is a unique identifier that includes a human-readable type name.
Instead of seeing d6157329-4640-8e30-8012-3456789abcde in your logs or database,
you see user.Br2flcNDfF6LYICnT and immediately know it's a user ID.
Benefits over plain UUIDs:
Every TNID can be represented in two string formats:
user.Br2flcNDfF6LYICnT
Human-readable. Use in logs, URLs, APIs, and anywhere humans might see it.
d6157329-4640-8e30-8012-3456789abcde
Standard format. Use with existing UUID tooling and libraries that expect this format.
These are the same 128 bits — convert freely between them. Store as a string (either format) or as binary (UUID/u128 columns).
The name is the type prefix (e.g., user in user.Br2flcNDfF6LYICnT).
Rules:
a-z and digits 0-4 onlyExamples:
user, post, item, orgtx, evt, req, joba, b1, c2dTNIDs have a 2-bit variant field, allowing 4 variants:
Like UUIDv7: contains a millisecond timestamp. IDs sort chronologically.
Use when: You want to sort by creation time.
Like UUIDv4: 100 bits of random entropy. Maximum unpredictability.
Use when: You don't need chronological sorting.
V2 and V3 are reserved for future use.
When in doubt, use V0. Time-ordering is usually helpful.
In languages that support it, the type system prevents mixing different TNID types. This catches bugs at compile time:
const userId: UserId = UserId.new_v0();
const postId: PostId = PostId.new_v0();
getUser(userId); // OK
getUser(postId); // Compile error!
The compiler catches the bug before your code runs. No more accidentally passing a post ID to a user lookup.
import { Tnid, TnidType } from "@tnid/core";
// Define your ID type
const UserId = Tnid("user");
type UserId = TnidType<typeof UserId>;
// Generate IDs
const id: UserId = UserId.new_v0();
console.log(id); // "user.Br2flcNDfF6LYICnT"
// Convert to UUID for database storage
const uuid = UserId.toUuidString(id);
// "d6157329-4640-8e30-8012-3456789abcde"
// Parse from string
const parsed = UserId.parse("user.Br2flcNDfF6LYICnT");
use tnid::Tnid;
// Define your ID type
type UserId = Tnid<"user">;
// Generate IDs
let id: UserId = UserId::new_v0();
println!("{}", id); // "user.Br2flcNDfF6LYICnT"
// Convert to UUID
let uuid = id.to_uuid();
// Parse from string
let parsed: UserId = "user.Br2flcNDfF6LYICnT".parse()?;