Getting Started

From an Unconfigured Repository to a Translated One

Install

npm install -g @the-i18n-kit/cli

Or prefix every command with npx -y @the-i18n-kit/cli@latest. The binary is the-i18n-cli either way.

1. Write a Config From Detection

the-i18n-cli init --dryRun

That reports the config it would write and touches no disk. Read detected first: if adapter is not the framework you expected, pin one before going further. derivesLocaleConfig: true means the adapter reads locales and directories out of your project's own files, which is why the generated config names neither.

Drop --dryRun to write .i18n-mcp.json. init refuses to overwrite an existing file without --force.

2. Take a Health Check

the-i18n-cli status

Coverage per locale and per layer — a scoped locale directory. A single-app project has one layer, named root. Output is JSON whenever stdout is not a terminal, so the-i18n-cli status | jq .summary works with no flag.

Check two fields in summary and fix them in the config file:

  • referenceLocale is what everything is compared against. Adapters that cannot derive it take the alphabetically first locale, which is how a project with English source strings ends up measured against de-DE. Set defaultLocale.
  • protectedLocales is empty until you say otherwise, so every locale is a candidate for machine translation. Name the ones a person maintains.
.i18n-mcp.json
{
  "$schema": "node_modules/@the-i18n-kit/mcp/schema.json",
  "defaultLocale": "en-US",
  "protectedLocales": ["de-DE"]
}

Run status again: a protected locale drops out of the counted set, so the completion percentage moves. That is the confirmation the file was read.

3. Catch Keys That Render Raw

status compares locale files against each other. It cannot see a key your code calls that no locale file defines — the failure your users notice first.

the-i18n-cli check
{
  "undefinedKeys": [
    {
      "key": "booking.cancelled",
      "app": "default",
      "searchedLayers": ["root"],
      "usages": [{ "file": "src/App.vue", "line": 17 }]
    }
  ],
  "uncertainKeys": [],
  "summary": { "usedKeysChecked": 5, "undefinedCount": 1, "uncertainCount": 0 }
}

That run exits 2: the command worked and found what it always fails on. Exit 1 would mean the run itself fell over — see the agent contract. uncertainKeys holds references the static scanner could not resolve; they never count as findings.

4. Translate What Is Missing

the-i18n-cli translate --dryRun

summary.targetLocales is the check that step 2 landed: the locale you protected is not in it. Without --layer, every locale-backed layer is translated in one run and the totals are aggregated.

the-i18n-cli translate --provider google --model gemini-2.5-flash --apiKey <your-api-key>

Substitute your own key, or export the provider's key variable instead. --provider accepts openai, anthropic and google, and --model is required with it. Leave --provider off and nothing is translated: every key comes back skipped with reason no-provider, which is the mode an agent drives through the MCP server.

Provider output is validated before it is written — placeholder parity per plural variant, and matching plural-variant counts — so a value that fails lands in failed rather than in your locale file. See translation modes.

A partly failed run writes what succeeded and exits 0. The failed keys stay missing and the next run retries them, so a green run is not proof of a complete one. Add --fail-on-failed if that should block.

Next

  • GitHub Actions or GitLab CI — gate a pipeline on the commands above.
  • Configuration — a glossary and tone notes are what make provider translations sound like your product.
  • Monorepos — what changes when several apps consume several layers.
  • CLI reference — every command, generated from its definition.
Copyright © 2026