The Lingo.dev CLI translates your web app's resource files - JSON, YAML, XLIFF, PO, or PHP - through a configured localization engine. Set up i18n in your framework, point the CLI at your translation files, and run.
How It Works#
Every web framework has an i18n library that loads translations from resource files - JSON for React, XLIFF for Angular, PO for Django, and so on. The CLI translates those files directly, so the framework picks up translations without any code changes.
Set up i18n in your framework
Use your framework's official i18n library to add locale-aware routing, a translation function, and source-language resource files. Each framework section below links to the official setup guide.
Configure the CLI
Run lingo init to create a .lingo/config.json with your source and target locales plus the file patterns to translate, then lingo link to attach your organization and engine. The CLI auto-detects each file's format from its extension, so no bucket type is needed. Commit .lingo/config.json.
Run translations
Run lingo push and the CLI translates your resource files through the localization engine - glossary rules, brand voice, and model selection apply automatically.
Prerequisites#
Install the CLI and authenticate:
npm install -g @lingo.dev/cli
lingo loginThe CLI requires Node.js 22+. In CI, skip the interactive login and pass a key with --api-key or the LINGO_API_KEY environment variable.
Every CLI run sends content through a localization engine - the configuration that determines which LLM model, glossary, brand voice, and instructions apply. Create one in the Lingo.dev dashboard and generate an API key. lingo link writes the engine's orgId and engineId into .lingo/config.json.
AI-assisted setup
The i18n MCP can scaffold your framework's entire i18n infrastructure automatically. Connect it to Claude Code, Cursor, or GitHub Copilot and prompt "Set up i18n" - the agent follows a 13-step checklist to configure routing, translation files, and a language switcher.
JavaScript Frameworks#
The locale segment in each pattern is substituted per target locale - public/locales/en/translation.json becomes public/locales/de/translation.json, and so on. The source path must contain the source locale code.
react-i18next loads translations from JSON files and provides a useTranslation hook that maps keys to translated strings at runtime.
{
"orgId": "org_...",
"engineId": "eng_...",
"sourceLocale": "en",
"targetLocales": ["es", "fr", "de", "ja"],
"files": [{ "pattern": "public/locales/en/translation.json" }]
}Server-Side Frameworks#
Laravel ships with built-in localization that loads translations from PHP files organized by locale directory.
{
"orgId": "org_...",
"engineId": "eng_...",
"sourceLocale": "en",
"targetLocales": ["es", "fr", "de", "ja"],
"files": [{ "pattern": "lang/en/messages.php" }]
}Running Translations#
With .lingo/config.json in place, translate all resource files in one command:
lingo pushThe CLI reads your source locale files, computes what changed since the last run using the lockfile (.lingo/lock.json, committed alongside your config), translates only the delta, and writes results to target locale files. Existing translations are preserved - the CLI only fills in missing or updated strings.
On the first run, or after adding a new target locale, translate everything from scratch:
lingo push --backfill-missingScope a run to a subset of files by passing a glob:
lingo push "messages/**"To fetch the latest translations elsewhere (for example on another machine or in a build step) without translating, run lingo pull. Use lingo check as a deploy gate to verify translations are up to date.
