---
title: "Verbatra: i18n CLI that translates only the changed keys"
description: "Verbatra is an open source i18n CLI and SDK. It finds missing and changed keys in your locale files and translates only those with your own provider key."
---

# Translate only what changed

Verbatra fills the missing keys in your locale files, gives your coding agent an MCP server, and fails CI when translations drift.

- [Get started](https://verbatra.kreitz-webdev.de/docs/quickstart.md)

```sh
npm i -D @verbatra/cli
```

## Works with the locale files and providers you already use

### File formats

- i18next JSON
- vue-i18n JSON
- next-intl JSON
- ngx-translate JSON
- XLIFF
- YAML
- Flutter ARB
- Java/Spring .properties
- Apple .strings
- Xcode String Catalog
- Android strings.xml
- gettext .po/.pot
- INI
- .NET .resx

[All formats](https://verbatra.kreitz-webdev.de/docs/formats.md)

### Providers

- Anthropic
- OpenAI
- Gemini
- DeepL
- Google Cloud Translation
- OpenCode (New, Available from 0.12.0)
- OpenAI-compatible
- LibreTranslate (New, Available from 0.12.0)

[All providers](https://verbatra.kreitz-webdev.de/docs/providers.md)

## One run, one locale

2 keys leave your machine, 12 stay put

```text
de: 2 translated, 12 unchanged, 359 tokens (318 in, 41 out)
```

## Everything around the diff

A CLI, an SDK, a local Studio and an MCP server, all reading the same lock file.

### Translate: Pay for 4 strings, not 28

```text
$ npx @verbatra/cli translate
  de: 2 translated, 12 unchanged, 359 tokens (318 in, 41 out)
  fr: 2 translated, 12 unchanged, 366 tokens (322 in, 44 out)
  total: 725 tokens (640 in, 85 out)
2 succeeded, 0 partial, 0 failed
```

### Check: Drift fails the pull request

`exit 1`

The check exits 1 while a locale is missing keys. It needs no API key, so it runs on every pull request.

### Integrity: Placeholders arrive intact

- de: Willkommen zurück, {name}!
- es: ¡Bienvenido de nuevo, {name}!
- fr: Bienvenue, {name} !
- ja: おかえりなさい、{name}さん！

### Agents: Your coding agent fixes translations

Register the MCP server for the project, and the agent can read status and fix translations. Tools that spend provider tokens stay off until you allow them.

```sh
claude mcp add --transport stdio --scope project verbatra -- npx -y @verbatra/mcp
```

## Translate a string with the SDK

Pick a string and watch the SDK call translate it into every language below. Placeholders stay exactly in place.

Pre-generated with the Verbatra SDK and Gemini, not live.

- Provider: Gemini
- Model: `gemini-2.5-flash`
- Generated: October 16, 2026

Every pre-generated result, one row per source string:

| Source (English) | German | Spanish | French | Japanese |
| --- | --- | --- | --- | --- |
| Save changes | Änderungen speichern | Guardar cambios | Enregistrer les modifications | 変更を保存 |
| Sign in | Anmelden | Iniciar sesión | Se connecter | サインイン |
| Welcome back, {name}! | Willkommen zurück, {name}! | ¡Bienvenido de nuevo, {name}! | Bienvenue, {name} ! | おかえりなさい、{name}さん！ |
| You have {count} new messages | Sie haben {count} neue Nachrichten | Tienes {count} mensajes nuevos | Vous avez {count} nouveaux messages | {count}件の新しいメッセージがあります |
| Your cart is empty. | Ihr Warenkorb ist leer. | Tu carrito está vacío. | Votre panier est vide. | カートは空です。 |
| Delete this file? | Diese Datei löschen? | ¿Eliminar este archivo? | Supprimer ce fichier ? | このファイルを削除しますか？ |
| Don't show this again | Nicht wieder anzeigen | No mostrar esto de nuevo | Ne plus afficher ceci | 今後表示しない |
| Settings | Einstellungen | Configuración | Paramètres | 設定 |
| Only changed keys get translated. | Es werden nur geänderte Schlüssel übersetzt. | Solo las claves modificadas se traducen. | Seules les clés modifiées sont traduites. | 変更されたキーのみが翻訳されます。 |
| Verbatra | Verbatra | Verbatra | Verbatra | Verbatra |

```ts title="translate.ts"
import { defineConfig, loadConfig, translate } from "@verbatra/sdk";

const config = await loadConfig({
  configOverride: defineConfig({
    sourceLocale: "en",
    targetLocales: [
      "de",
      "es",
      "fr",
      "ja",
    ],
    format: "next-intl-json",
    files: { pattern: "messages/{locale}.json" },
    provider: {
      id: "gemini",
      options: { model: "gemini-2.5-flash", maxOutputTokens: 2048 },
    },
  }),
});

const summary = await translate({ config });
```

Read more:

- [SDK quickstart](https://verbatra.kreitz-webdev.de/docs/sdk-quickstart.md)
- [SDK reference](https://verbatra.kreitz-webdev.de/docs/sdk.md)
- [Providers](https://verbatra.kreitz-webdev.de/docs/providers.md)

## Features: Built for the whole translation workflow

From the first string in your source code to the reviewed translation in production.

- [Review in Studio](https://verbatra.kreitz-webdev.de/docs/cli/studio.md): A local dashboard over your project: browse every locale, work through the review queue and edit values in place.
- [Hand off to people](https://verbatra.kreitz-webdev.de/docs/cli/export.md): Export an Excel workbook for a translator and import it back. Imported values stay protected from later machine runs.
- [Extract from source](https://verbatra.kreitz-webdev.de/docs/cli/extract.md): Scan your code for translation calls and add the new keys to the source locale before anyone translates them.
- [Watch while you build](https://verbatra.kreitz-webdev.de/docs/cli/watch.md): Keep a watcher running in development, and every change to the source locale is translated as you save.
- [Typed keys](https://verbatra.kreitz-webdev.de/docs/cli/types.md): Generate TypeScript declarations for your keys and message arguments, so a typo in a key fails the build.
- [Know before you spend](https://verbatra.kreitz-webdev.de/docs/cli/doctor.md): Doctor checks the setup without an API key, and an estimate sizes a run before it costs anything.

## Before you install Verbatra

Short answers, each with the docs page that goes deeper.

### Is Verbatra free?

Yes. Verbatra is free and open source under the [MIT license](https://github.com/verbatra/verbatra/blob/main/LICENSE), and you pay only your provider for the keys that changed; [estimating cost](https://verbatra.kreitz-webdev.de/docs/estimating-cost.md) sizes a run first.

### Which translation providers does Verbatra support?

Anthropic, OpenAI, Gemini, DeepL, Google Cloud Translation, OpenCode, OpenAI-compatible, and LibreTranslate. Set one in `provider`, or `none` when only people translate; the [providers page](https://verbatra.kreitz-webdev.de/docs/providers.md) covers each.

### Does Verbatra send my strings or API keys anywhere?

Only to the provider you configure, when a command translates; there is no telemetry. Keys stay in environment variables, and [data handling](https://verbatra.kreitz-webdev.de/docs/data-handling.md) lists what each provider receives.

### Can Verbatra fail a pull request when translations are missing?

Yes. `verbatra check` exits 1 while a locale has missing or stale keys, with no API key needed; the [GitHub Action](https://verbatra.kreitz-webdev.de/docs/github-action.md) runs it on pull requests.

### Does Verbatra re-translate strings that did not change?

No. Only new and changed keys go to your provider; a committed [lock file](https://verbatra.kreitz-webdev.de/docs/the-lock-file.md) records what is already translated.

In the docs:

- [Quickstart](https://verbatra.kreitz-webdev.de/docs/quickstart.md)
- [Translation safety](https://verbatra.kreitz-webdev.de/docs/translation-safety.md)
- [Full comparison](https://verbatra.kreitz-webdev.de/compare)

## Start with a dry run

Before you spend a token

After init, a dry run needs no API key, writes nothing and lists exactly which keys a real run would send.

```sh
npx @verbatra/cli translate --dry-run
```
