Keep every locale file in step with your source.
verbatra translates your i18n locale files incrementally: it sends only the new and changed strings to the provider you configure, checks every result, and writes the files back in place.
pnpm add -D @verbatra/cliAn example verbatra command-line session.
- verbatra init
- ✓ created verbatra.config.ts
- source en · targets de, es, fr
- provider gemini · key from GEMINI_API_KEY
- verbatra translate
- diff en.json · 12 new · 0 changed · 108 unchanged
- de 12 translated · 108 unchanged · 0 withheld
- es 12 translated · 108 unchanged · 0 withheld
- fr 12 translated · 108 unchanged · 0 withheld
- ✓ 36 keys translated in 5.4s · 0 skipped · lock updated
- verbatra diff
- en.json · 120 keys · source of truth
- de 2 new · 1 changed · 117 up to date
- es 0 new · 0 changed · 120 up to date
- fr 5 new · 0 changed · 115 up to date
- 8 keys would be sent · run verbatra translate to apply
- verbatra watch
- watching en.json for changes
- en.json changed · 1 new key
- de 1 translated · 0 withheld
- ✓ 3 keys translated · waiting for changes
The problem
You hand-maintain one source locale. Every other locale file drifts as that source evolves: new keys are missing from the targets, edited source strings leave stale translations behind, and deleted keys linger as orphans. Catching up by hand does not scale, and retranslating everything on every change is slow, costs provider tokens for strings that were already fine, and churns text your team has reviewed.
How verbatra solves it
A committed lock file, verbatra.lock.json, records for every translated key the hash of the source string its translation came from. Each run reads the source locale, diffs every target against it and against that baseline, and sends only the missing and changed keys to the provider. Keys that are still current are left alone: run translate twice in a row and the second run makes no provider call at all.
Every string the provider returns is checked before it is written: placeholder integrity and ICU integrity are enforced, and a translation that breaks either is withheld instead of shipped, then retried on the next run. The read-only check and diff commands report drift without writing anything, so CI can gate on their exit codes.
verbatra reads and writes eight formats (i18next, vue-i18n, next-intl, and ngx-translate JSON, XLIFF, YAML, Flutter ARB, and Java/Spring properties) and translates through five providers (Anthropic, OpenAI, Gemini, DeepL, and any OpenAI-compatible server, including local ones) behind one interface. See Formats and Providers.
The packages
verbatra ships as three npm packages:
- @verbatra/cli provides the
verbatrabinary with eight commands:init,translate,watch,check,diff,export,import, andstudio. It is a thin wrapper over the SDK, so everything it does is available programmatically too. Start here. - @verbatra/sdk is the engine underneath: one-shot
translate(), long-runningwatch(), read-onlycheck()anddiff(), the Excel workbook round-trip for human translators, and config loading. Use it directly from scripts, build tools, or CI. See the SDK. - @verbatra/studio is Verbatra Studio, a local dashboard over your project with built-in editing and a review queue. The CLI starts it with
verbatra studio; provider spend from Studio stays off unless you pass--allow-spend. See Review in Studio.