A UUID type with base62 text encoding for Go. 22 characters, URL-safe, zero dependencies beyond google/uuid.
standard: 019d6908-bc8c-71ac-a33c-16585d16be42 (36 chars)
uuid62: 032vbBwxOxoi5h6hiPCfPW (22 chars)
prefixed: cus_032vbBwxOxoi5h6hiPCfPW (26 chars)
Storage is always 16 bytes — identical to a standard UUID on disk. The encoding is purely a text representation concern.
Bonus: UUIDs which are double-click friendly!
go get github.com/twopow/uuid62
import "github.com/twopow/uuid62"
// Generate
id := uuid62.New() // random (v4)
id := uuid62.NewOrdered() // time-ordered (v7)
// Parse (accepts base62, hex, or dashed hex)
id, err := uuid62.Parse("032vbBwxOxoi5h6hiPCfPW")
id, err := uuid62.Parse("019d6908-bc8c-71ac-a33c-16585d16be42")
// Render
id.String() // "032vbBwxOxoi5h6hiPCfPW"
id.Std() // google/uuid.UUID, for interop
// Works in structs with JSON and SQL out of the box
type User struct {
ID uuid62.UUID `json:"id" db:"id"`
Name string `json:"name" db:"name"`
}Type-safe, Stripe-style prefixed IDs via generics. The prefix exists only in the text form — storage is still raw 16-byte UUID.
// Define a tag type per domain entity
type customerTag struct{}
func (customerTag) Prefix() string { return "cus" }
type eventTag struct{}
func (eventTag) Prefix() string { return "evt" }
// Create type aliases
type CustomerID = uuid62.Prefixed[customerTag]
type EventID = uuid62.Prefixed[eventTag]
// Generate
cid := uuid62.NewPrefixed[customerTag]()
fmt.Println(cid) // "cus_032vbBwxOxoi5h6hiPCfPW"
// Parse (prefix is optional on input)
cid, err := uuid62.ParsePrefixed[customerTag]("cus_032vbBwxOxoi5h6hiPCfPW")
cid, err := uuid62.ParsePrefixed[customerTag]("032vbBwxOxoi5h6hiPCfPW")
// Type safety — this won't compile:
// var eid EventID = cid
// Convert between prefixed and bare
bare := cid.Bare() // uuid62.UUID
back := uuid62.Prefixed[customerTag](bare) // re-tagJSON, sql.Scanner, and driver.Valuer all work automatically. The database always sees native 16-byte UUID; the prefix appears only in text output.
BenchmarkEncode 586 ns/op 1 allocs/op
BenchmarkDecode 131 ns/op 0 allocs/op
BenchmarkNew 204 ns/op 1 allocs/op
BenchmarkNewOrdered 240 ns/op 1 allocs/op