nicksnyder/go-i18n
nicksnyder/go-i18n has 3,554 GitHub stars and 287 forks. GitHot measured +2 in 7 days. Last checked 2026-11-09 15:32 UTC. Last push 2026-11-01.
Translate your Go program into multiple languages.
Measured star growth
- in 24h
- Update delayed
- in 7 days
- +2
- in 15 days
- Update delayed
- in 1 month
- Update delayed
Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.
README.md
Originalgo-i18n
go-i18n is a Go package and a command that helps you translate Go programs into multiple languages.
- Supports pluralized strings for all 200+ languages in the Unicode Common Locale Data Repository (CLDR).
- Code and tests are automatically generated from CLDR data.
- Supports strings with named variables using text/template syntax.
- Supports message files of any format (e.g. JSON, TOML, YAML).
Package i18n
The i18n package provides support for looking up messages according to a set of locale preferences.
import "github.com/nicksnyder/go-i18n/v2/i18n"
Create a Bundle to use for the lifetime of your application.
bundle := i18n.NewBundle(language.English)
Load translations into your bundle during initialization.
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
bundle.LoadMessageFile("es.toml")
Create a Localizer to use for a set of language preferences.
func(w http.ResponseWriter, r *http.Request) {
lang := r.FormValue("lang")
accept := r.Header.Get("Accept-Language")
localizer := i18n.NewLocalizer(bundle, lang, accept)
}
Use the Localizer to lookup messages.
localizer.Localize(&i18n.LocalizeConfig{
DefaultMessage: &i18n.Message{
ID: "PersonCats",
One: "{{.Name}} has {{.Count}} cat.",
Other: "{{.Name}} has {{.Count}} cats.",
},
TemplateData: map[string]interface{}{
"Name": "Nick",
"Count": 2,
},
PluralCount: 2,
}) // Nick has 2 cats.
Command goi18n
The goi18n command manages message files used by the i18n package.
go install -v github.com/nicksnyder/go-i18n/v2/goi18n@latest
goi18n -help
Extracting messages
Use goi18n extract to extract all i18n.Message struct literals in Go source files to a message file for translation.
# active.en.toml
[PersonCats]
description = "The number of cats a person has"
one = "{{.Name}} has {{.Count}} cat."
other = "{{.Name}} has {{.Count}} cats."
Translating a new language
Create an empty message file for the language that you want to add (e.g.
translate.es.toml).Run
goi18n merge active.en.toml translate.es.tomlto populatetranslate.es.tomlwith the messages to be translated.# translate.es.toml [HelloPerson] hash = "sha1-5b49bfdad81fedaeefb224b0ffc2acc58b09cff5" other = "Hello {{.Name}}"After
translate.es.tomlhas been translated, rename it toactive.es.toml.# active.es.toml [HelloPerson] hash = "sha1-5b49bfdad81fedaeefb224b0ffc2acc58b09cff5" other = "Hola {{.Name}}"Load
active.es.tomlinto your bundle.bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal) bundle.LoadMessageFile("active.es.toml")
Translating new messages
If you have added or changed messages in your program:
- Run
goi18n extractto updateactive.en.tomlwith the new messages. - Run
goi18n merge active.*.tomlto generate updatedtranslate.*.tomlfiles. - Translate all the messages in the
translate.*.tomlfiles. - Run
goi18n merge active.*.toml translate.*.tomlto merge the translated messages into the active message files. - Delete the
translate.*.tomlfiles. They are not needed until you add or change messages again.
translate.*.toml files are regenerated from scratch on every merge, so they only contain the messages that still need to be translated:
- messages that are new,
- messages whose source text or description changed since they were translated (detected using
hash), and - messages that are missing a translation for one of the language's plural forms (e.g. French needs
one,many, andother). The forms that are already translated are included too, so the translator can see them for context.
Messages that are already translated stay in active.*.toml and are not repeated in translate.*.toml, so you never need to translate them again.
The hash that goi18n merge writes for each translated message records which version of the source message it was translated from. Keep it in your active.*.toml files: without it, goi18n merge cannot tell when the source message has changed and will not ask for the translation to be updated. Hashes are only used by goi18n merge and have no effect at runtime. The source language's active.*.toml file does not need hashes, so it has none.
For more information and examples:
- Read the documentation.
- Look at the code examples and tests.
- Look at an example application.
License
go-i18n is available under the MIT license. See the LICENSE file for more info.
Explore related projects
codecrafters-io/build-your-own-x
Master programming by recreating your favorite technologies from scratch.
561,646 starspublic-apis/public-apis
A collective list of free APIs
498,017 starsmorluto/rea
Reverse engineer anything with agents, from app behavior down to native binaries.
450,495 starsopenclaw/openclaw
The AI that really does things. Any OS. Any Platform. The lobster way. 🦞
394,310 stars