xid
A dependency-free Go library for generating compact, sortable, globally unique 12-byte IDs with no configuration required.
Repository Health
Technical Analysis
xid generates globally unique, k-sortable identifiers for Go applications without requiring any external coordination service, machine configuration, or central ID-issuing server. Each 12-byte ID packs a 4-byte Unix timestamp, a 3-byte machine identifier derived from the host’s hardware ID or hostname, a 2-byte process ID, and a 3-byte atomic counter seeded with a random starting value, following the same layout as MongoDB’s ObjectID. IDs are encoded as a 20-character, URL-safe, lowercase base32hex string that preserves sort order, making xid a compact alternative to UUIDs for request IDs, database primary keys, and distributed-system identifiers.
The library ships as a single importable package with a minimal API — xid.New() mints an ID and accessor methods recover its embedded timestamp, machine, and process components — plus implementations of encoding.TextMarshaler, json.Marshaler, and database/sql/driver’s Valuer/Scanner interfaces so IDs serialize and persist without extra glue code. The README’s own benchmarks show generation costing tens of nanoseconds per call with a single allocation, notably faster than common UUID implementations, and the package lazily resolves the machine ID on first use so merely importing it costs nothing until an ID is actually generated.
What You Get
- A single
xid.New()call that mints a sortable, globally unique ID with no configuration. - Built-in
encoding.TextMarshaler/json.Marshalersupport for drop-in use as JSON API fields or struct members. - SQL
driver.Valuer/Scannerimplementations for storing and reading IDs directly in database columns. - Accessor methods (
Time(),Machine(),Pid(),Counter()) to inspect the components embedded in an existing ID. - An
XID_MACHINE_IDenvironment variable override for pinning the machine component in containerized or ephemeral environments.
Common Use Cases
- Generating request/trace IDs for HTTP middleware and structured logging.
- Using xid values as sortable primary keys in relational or document databases instead of auto-increment integers or UUIDs.
- Producing compact, URL-safe identifiers for public-facing resources such as short links, uploaded file names, or session tokens.
- Deduplicating events across distributed workers without a shared ID-issuing service.
Under The Hood
Architecture
xid is a single, tightly-scoped Go package built around a fixed 12-byte array type (ID) rather than a struct, keeping the value cheap to copy and compare. Core generation state — a random-seeded atomic counter, an os.Getpid()-derived process id, and a lazily-resolved machine id guarded by sync.Once — lives at package level in id.go and is mutated through New()/NewWithTime() using atomic operations rather than a mutex-protected struct, so the design favors a package-level singleton generator over an instantiable one. Platform-specific machine-id resolution is isolated behind Go build tags into per-OS files (hostid_darwin.go, hostid_linux.go, hostid_freebsd.go, hostid_openbsd.go, hostid_windows.go, hostid_fallback.go), each implementing a shared readPlatformMachineID() contract, so OS differences are resolved at compile time rather than through runtime branching. Errors are centralized in error.go behind one typed constant, and a small companion subpackage (b/) offers an alternate byte-array-only ID type for callers who don’t need the base32 encode/decode machinery. Because the id layout is unversioned and baked into every stored or serialized value, changing the byte layout would be a breaking change for every consumer of previously generated IDs.
Tech Stack
The module declares no third-party dependencies — go.mod pins only the Go toolchain version — and relies entirely on the standard library: crypto/rand and crypto/sha256 for randomness and machine-id hashing, encoding/binary for big-endian byte packing, sync/sync/atomic for the concurrency-safe counter and lazy machine-id init, and database/sql/driver for native SQL column support. Platform machine-id resolution shells out to ioreg on darwin and reads /etc/machine-id or the DMI product UUID on linux, falling back to hostname or a random value elsewhere. CI runs on GitHub Actions across a multi-OS matrix (Ubuntu, Windows, and multiple macOS versions), executing go vet and the race-detector test suite plus golangci-lint on every platform; there is no build or deployment step since the project ships as a library, not a binary.
Code Quality
Test coverage is extensive and disciplined: table-driven tests cover ID part extraction, string/byte round-tripping, and JSON/SQL marshaling; property-based tests via the standard library’s testing/quick package fuzz string decoding against both valid and invalid inputs; and dedicated concurrency tests exercise the lazy machine-id resolution path. Benchmarks are checked in alongside the tests for the hot generation and parsing paths. CI enforces go vet, the race detector, and golangci-lint across every supported platform on each push, so cross-platform regressions or data races are caught automatically rather than relying on manual review. Errors use a single typed constant rather than ad hoc string errors or silent failure, and the handful of panics are limited to genuinely unrecoverable init-time conditions, documented in the source. Naming and structure are idiomatic Go throughout, and low-level routines like the hand-rolled base32 encode/decode explicitly document their bounds-check elision as a deliberate performance tradeoff rather than an oversight.
API Design
The public surface is small and immediately usable: xid.New() returns a ready ID with no configuration object, options struct, or setup call required, matching the package’s stated “non configured” design goal. Interop is treated as core functionality rather than an afterthought — ID implements encoding.TextMarshaler/TextUnmarshaler, json.Marshaler/Unmarshaler (with an explicit nil-ID-to-null case), and database/sql/driver’s Valuer/Scanner, so a struct field or SQL column of type ID serializes correctly without adapter code. Every exported symbol carries a doc comment, and the package-level doc comment explains both the algorithm’s lineage (MongoDB’s ObjectID) and the reasoning behind the base32hex encoding choice over base64 or base36, backed by a comparison table and benchmark numbers in the README. The main ergonomic tradeoff is that the generator is package-level global state (with an XID_MACHINE_ID env-var escape hatch) rather than an injectable type, which is simple to use but offers no way to run multiple independent, test-isolated generators in the same process.
Used by 7 apps in this directory
Harness Open Source
Developer Tools · Devops · Code Editors
A unified open source DevOps platform combining Git hosting, CI/CD pipelines, cloud development environments, and artifact registries in a single self-hosted system.
highlight.io
Developer Tools · Analytics · Monitoring
Open-source full-stack monitoring that unifies session replay, error tracking, logging, and distributed tracing so you can stop context-switching between tools.
NetBird
Security
Replace your VPN with a zero-trust WireGuard overlay network that auto-connects devices, enforces SSO and posture checks, and deploys in under 5 minutes.
OpenReplay
Analytics
Self-hosted session replay and product analytics suite that lets you see exactly what users do on your web app — without sending data to third parties.
PrivateCaptcha
Security · Authentication
Privacy-first, self-hostable Proof-of-Work CAPTCHA for GDPR-compliant bot protection.
SpiceDB
Security · Authentication · Databases
An open source, Google Zanzibar-inspired authorization database that models permissions as relationships and evaluates fine-grained access checks at massive scale with single-digit millisecond latency.
ZITADEL
Authentication
Open-source, API-first identity platform delivering multi-tenancy, Passkeys, OIDC, SAML, and SCIM without vendor lock-in.