go-i18n
Go i18n library for translating apps into 200+ languages with full CLDR plural support and a companion CLI.
Repository Health
Technical Analysis
go-i18n is a Go package and companion CLI for translating applications into multiple languages. The i18n package provides a Bundle for loading translation message files and a Localizer for looking up messages based on a set of language preferences, with plural-aware rendering for all 200+ languages defined in the Unicode CLDR plural rules.
Alongside the library, the goi18n command extracts translatable Message literals from Go source into message files and merges newly translated files back into the active set, giving teams a lightweight workflow for keeping translations synced with code changes without needing an external localization platform.
What You Get
- A Bundle type for loading translation message files in JSON, TOML, or YAML (or any format via a registered UnmarshalFunc)
- A Localizer that matches Accept-Language headers or explicit locale tags to the best available translation
- Full CLDR plural-form support (zero/one/two/few/many/other) for 200+ languages, code-generated from Unicode’s plural rules data
- The goi18n CLI for extracting Message literals from source and merging translations across active/translate file pairs
- text/template-style variable interpolation inside translated strings via TemplateData
Common Use Cases
- Localizing HTTP handlers by parsing the Accept-Language header into a Localizer per request
- Extracting new translatable strings from a Go codebase before sending them to translators
- Merging translator output back into active message files as part of a release workflow
- Embedding locale files with go:embed and loading them via LoadMessageFileFS for a single static binary
Under The Hood
Architecture
The module splits cleanly into a public i18n package (Bundle, Localizer, Message, MessageTemplate) and two supporting internals: internal/plural, which holds CLDR plural-rule tables and their form-selection logic, and i18n/template, a small pluggable template-execution abstraction consumed by Localizer.Localize. Bundle owns per-language-tag maps of parsed MessageTemplates and builds a golang.org/x/text/language.Matcher for locale negotiation, while Localizer wraps a Bundle plus a caller’s language preferences and resolves the best-matching tag before executing the message template with plural and interpolation data. The separate goi18n command reuses the same i18n parsing code to extract Message literals from Go source (extract_command.go) and to diff/merge active vs. translate message files (merge_command.go), so the CLI and library never duplicate message-file logic. If the core Bundle/Localizer split changed, both the library API and the CLI’s extract/merge commands would need to change together.
Tech Stack
Written in Go 1.24+ with a deliberately small dependency set: github.com/BurntSushi/toml and go.yaml.in/yaml/v3 for message-file formats, and golang.org/x/text for language-tag parsing and matching (JSON support uses the standard library encoding/json). Releases are built and published with GoReleaser, CI runs on GitHub Actions across two Go version channels, and golangci-lint enforces linting on the latest channel. No runtime web framework or database dependency — the whole module is a self-contained library plus CLI binary.
Code Quality
The repository carries 17 _test.go files exercising the bundle, localizer, parser, message, and plural-rule logic, and CI runs go test -race with coverage uploaded to Codecov, so both concurrency safety and coverage are actively tracked. Errors are modeled as explicit typed values (MessageNotFoundErr, invalidPluralCountErr, messageIDMismatchErr, mixedKeysError) with dedicated Error() implementations rather than ad hoc fmt.Errorf strings, and public API naming is consistent (New*, Must* panic-on-error variants, Load*/Parse* pairs). Combined with golangci-lint gating merges, this reflects a mature, actively maintained testing and error-handling discipline.
API Design
The public surface favors a small number of composable types over configuration objects: construct one Bundle per process, register unmarshal functions once, then create a lightweight Localizer per request or per language preference. Must* variants (MustLoadMessageFile, MustLocalize) trade explicit error handling for terser call sites during startup, and LocalizeConfig centralizes the optional knobs (plural count, template data, custom template parser) behind a single struct so the common case (Localize with just a message ID) stays simple. Godoc comments are present on essentially every exported type and method, and the CLI mirrors the library’s extract/merge mental model, keeping the developer experience consistent between writing code and managing translation files.
Used by 4 apps in this directory
1Panel
Devops · Hosting Control Panel · Monitoring
The only open-source VPS control panel with native AI agent runtime — deploy websites, Docker stacks, and local LLMs from one web interface.
Hanko
Security · Authentication
Open source, self-hostable authentication platform with passkeys, SAML SSO, and OAuth — the privacy-first alternative to Auth0 and Clerk.
Mattermost
Team Chat · Collaboration · Devops
Open core, self-hosted team collaboration with chat, AI agents, voice calling, and deep DevOps integrations — all under your control.
ZITADEL
Authentication
Open-source, API-first identity platform delivering multi-tenancy, Passkeys, OIDC, SAML, and SCIM without vendor lock-in.