Skip to main content
New β€” semantic translation QA

Catch broken translationsbefore you ship them

Missing keys, dropped placeholders and collapsed plurals β€” caught in CI, with no API key at all.

terminal
$ npx @shipi18n/cli check ./locales -s en
πŸ”Ž shipi18n check β€” nested layout, source 'en', 2 target language(s) βœ“ de  coverage 100.0%  0 error(s), 0 warning(s)βœ— es  coverage 100.0%  3 error(s), 1 warning(s)    error  common:cart.items  placeholder-missing β€” dropped {{count}}    error  home:hero.title  placeholder-missing β€” dropped {{name}}    warning  home:cta.note  untranslated β€” identical to source βœ— check failed: 3 error(s)   β†’ exit 1

Found broken keys? The same engine retranslates exactly those keys β€” placeholders validated, nothing else touched.

No key, no account, no config file. Add your own LLM key only for the semantic pass.

Your key, your model

Bring your own OpenAI or Anthropic key β€” or plug in any model with a ten-line adapter. You pay your provider directly, at cost, with no markup in between.

No account, no server

Nothing to sign up for and nothing to host. The packages run on your machine or in your CI, and your source strings never pass through our infrastructure.

Apache-2.0, all of it

Every package is open source, from the translation engine to the GitHub Action. Read the prompts, fork the engine, or vendor it into your own build.

The semantic pass

The bug key-diffing can't see

Every key present, every placeholder intact β€” and the Spanish says the opposite of the English. Structural checks pass this file. Reading it is the only way to catch it.

Source

en.json
{
  "saved": "Your changes were saved successfully."
}

Translation

es.json
{
  "saved": "No se pudieron guardar tus cambios."
}
terminal
$ npm i -D @shipi18n/cli @anthropic-ai/sdk
npx shipi18n check ./locales -s en --semantic
semantic: judged 1 (0 cached), flagged 1, 3 model call(s) ⚠ es  coverage 100.0%  0 error(s), 1 warning(s)    warning  saved  semantic-mistranslation β€” source says changes were             saved; translation says they could not be (opposite meaning) βœ“ check passed   β€” advisory: warns, still exits 0

With your own LLM key, the semantic pass reads each pair and flags mistranslations, omissions and additions β€” three passes, majority vote. Advisory by default: it warns, and fails your build only if you opt in with --semantic-fail.

Model Context Protocol

Check your translations from your editor

Add the MCP server to Claude Desktop, Cursor or any MCP client and validate your locale files by asking for it β€” missing keys, dropped placeholders, collapsed plurals, glossary breaches.

The validation tools need no API key. They are deterministic β€” no model call at all. For meaning-level review, the server hands your agent the translation pairs and the criteria, and your agent reasons about them with the model it already has. Translating new strings is the one thing that needs your own provider key.

View @shipi18n/mcp on npm
claude_desktop_config.json
{
  "mcpServers": {
    "shipi18n": {
      "command": "npx",
      "args": ["-y", "@shipi18n/mcp"]
    }
  }
}

The fix step: repair exactly what failed

check tells you which keys are broken. The same engine retranslates just those keys β€” and validates every placeholder on the way back in.

Source

en.json
{
  "greeting": "Hello, {{name}}!",
  "cart": "You have {{count}} items",
  "loaded": "Loaded %d of %s files",
  "terms": "I agree to the <b>Terms</b>",
  "ref": "See $t(common.greeting)"
}

Translated

es.json
{
  "greeting": "Β‘Hola, {{name}}!",
  "cart": "Tienes {{count}} artΓ­culos",
  "loaded": "Se cargaron %d de %s archivos",
  "terms": "Acepto los <b>TΓ©rminos</b>",
  "ref": "Ver $t(common.greeting)"
}

Interpolation, printf tokens, i18next references and inline HTML are extracted before the request and validated after it. A repair can't reintroduce the bug you just caught β€” and the keys that passed are never touched.

Five packages, one engine

Use the one that fits your workflow β€” they all share one engine: it checks, and it fixes what fails.

Five packages, one engine
PackageWhat it doesInstall
@shipi18n/cliCheck locale files in your terminal or CI β€” and retranslate just the keys that fail.npm i -D @shipi18n/cli
@shipi18n/mcpCheck, diff and review locale files from Claude Code, Cursor or any MCP client β€” no API key needed.npx @shipi18n/mcp
@shipi18n/coreThe engine itself β€” use it directly in Node.npm i @shipi18n/core
vite-plugin-shipi18nKeep translations current at build time β€” incremental, cached, placeholder-safe.npm i -D vite-plugin-shipi18n
shipi18n-github-actionRetranslate changed keys automatically on every push or pull request.uses: Shipi18n/shipi18n-github-action@v2
vite.config.js
import shipi18n from 'vite-plugin-shipi18n'

export default {
  plugins: [
    shipi18n({
      provider: 'anthropic',
      targetLanguages: ['es', 'fr', 'de'],
    }),
  ],
}

The fix step, automated

Repair belongs in the same place as the check β€” your build and your CI, not a browser tab someone has to remember to open.

  • Incremental by default: only failing and changed keys are retranslated. Everything that passed is left alone.
  • Run it in CI with the GitHub Action and commit the result, or open a pull request for review.
  • Build-time caching means a rebuild costs nothing when your strings haven't changed.

This page is the demo

Everything you're reading exists in 11 languages, and every one of them was produced and checked by the tool this page is about. Use the language switcher at the top and read it in Arabic, Japanese or German.

No sandbox, no sample data β€” just the output, in production, on the site you're already looking at.

Questions

Is this a translator?
It's a checker first. shipi18n check runs on locale files however they were produced β€” a human, an agency, another tool β€” and never asks you to change how you translate. The same engine can then repair what the check finds, retranslating exactly the failing keys. Repair, not replace.
What does it cost?
The packages are free and Apache-2.0 licensed. You pay your LLM provider for the tokens you use, at their prices, with nothing added on top. Translating a typical locale file into a handful of languages costs a few cents.
Where does my API key go?
Into your environment, and from there straight to your provider. There is no Shipi18n server in the path β€” we never see your key or your strings. Checking translations needs no key at all, because it runs no model.
Is the output actually good?
It's whatever your model produces, guided by prompts tuned for locale files rather than prose β€” the translator is told about neighbouring keys, placeholders and the fact that it's translating UI. Judge it from this site, which is translated the same way.
Which providers are supported?
Anthropic and OpenAI ship in the box. Any object with a complete(prompt) method is a valid adapter, so a local model, a proxy or an internal gateway takes about ten lines to wire up.
How many languages can it handle?
Any language your model speaks β€” there is no per-language list to buy into. Regional variants like pt-BR fall back to pt when you want them to.

Check your locale files in a minute

One command, nothing installed, no API key. Add a key later only if you want meaning checked too.

$ npx @shipi18n/cli check ./locales -s en
Star on GitHub

Apache-2.0 Β· works with Anthropic and OpenAI Β· MCP server included