Skip to content

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
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

Providers

  • Anthropic
  • OpenAI
  • Gemini
  • DeepL
  • Google Cloud Translation
  • OpenCodeNew (Available from 0.12.0)
  • OpenAI-compatible
  • LibreTranslateNew (Available from 0.12.0)

One run, one locale

2 keys leave your machine, 12 stay put

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

$ 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.

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.

en → de, es, fr, jadone
Source (en)Welcome back, {name}!
Source string
Target languages
Integrity check passed: 4 of 4 placeholders intactsent 1kept 9placeholders 4/4
translate.ts
@verbatra/sdk
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 });
translate()resolved

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

How these results were generated

Provider
Gemini
Model
gemini-2.5-flash
Generated
Every pre-generated result, one row per source string
Source (English)GermanSpanishFrenchJapanese
Save changesÄnderungen speichernGuardar cambiosEnregistrer les modifications変更を保存
Sign inAnmeldenIniciar sesiónSe connecterサインイン
Welcome back, {name}!Willkommen zurück, {name}!¡Bienvenido de nuevo, {name}!Bienvenue, {name} !おかえりなさい、{name}さん!
You have {count} new messagesSie haben {count} neue NachrichtenTienes {count} mensajes nuevosVous 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 againNicht wieder anzeigenNo mostrar esto de nuevoNe plus afficher ceci今後表示しない
SettingsEinstellungenConfiguraciónParamè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.変更されたキーのみが翻訳されます。
VerbatraVerbatraVerbatraVerbatraVerbatra

Features

Built for the whole translation workflow

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

  • Review in Studio

    A local dashboard over your project: browse every locale, work through the review queue and edit values in place.

  • Hand off to people

    Export an Excel workbook for a translator and import it back. Imported values stay protected from later machine runs.

  • Extract from source

    Scan your code for translation calls and add the new keys to the source locale before anyone translates them.

  • Watch while you build

    Keep a watcher running in development, and every change to the source locale is translated as you save.

  • Typed keys

    Generate TypeScript declarations for your keys and message arguments, so a typo in a key fails the build.

  • Know before you spend

    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 (opens in a new tab), and you pay only your provider for the keys that changed; estimating cost 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 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 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 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 records what is already translated.

Before you spend a token

Start with a dry run

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

npx @verbatra/cli translate --dry-run