Introduction#
Globetrotter is a code generator for applications that share translations across languages or frameworks. It reads TOML catalogs, validates the translations as one set, and writes:
- one JSON file for each spoken language, intended for runtime loading;
- TypeScript definitions for the translation structure;
- Rust types for translation keys and their declared arguments.
The translation text and the type information come from the same source files. A key cannot change in one output without changing in all of them.
Why split runtime data from generated types?#
Translation text changes for editorial reasons. Application code changes for behavioral reasons. Bundling both into generated source means a wording correction requires rebuilding the application; keeping everything as untyped JSON means misspelled keys and incorrect template arguments survive until runtime.
Globetrotter uses a narrower contract:
- Keys and argument declarations are build-time facts.
- The translated strings are runtime data.
- Every generated target is derived from the same catalog.
This gives a TypeScript or Rust compiler enough information to check application code while keeping the deployed translation files ordinary JSON.
The source model#
A translation file is a TOML table per key:
[account.greeting]
en = "Welcome back, {{name}}!"
de = "Willkommen zurück, {{name}}!"
fr = "Bon retour, {{name}} !"
arguments = { name = "string" }
[cart.summary]
en = "You have {{count}} items in your cart."
de = "Du hast {{count}} Artikel in deinem Warenkorb."
fr = "Vous avez {{count}} articles dans votre panier."
arguments = { count = "number" }
[navigation.sign_out]
en = "Sign out"
de = "Abmelden"
fr = "Se déconnecter"Each language is a field on the key. arguments describes the values used by the configured
template engine. In this example, account.greeting requires a string named name, while
navigation.sign_out has no arguments.
The config decides how those keys are named and which artifacts to write:
version: 1
configs:
app:
languages: [en, de, fr]
engine: handlebars
strict: true
check_templates: true
inputs:
- path: ./translations.toml
prefix: app
outputs:
json:
- ./generated/translations_{{language}}.json
typescript:
type: ./generated/translations.ts
rust:
- ./generated/translations.rsThe app prefix makes the first key app.account.greeting in generated output. Paths are resolved
relative to the config file, so the same config behaves consistently from a developer shell, a
build script, and CI.
Where it fits#
Globetrotter works well when:
- several services or frontends share a translation contract;
- translations must remain editable or deployable independently;
- template placeholders should be checked before release;
- generated bindings are preferable to hand-maintained key constants.
It does not render translations for your application. Use the runtime template engine or i18n library that fits your stack; Globetrotter prepares and validates the data and types it consumes.
Next: install the CLI or go straight to the quick start.