Locale file checkers compared
Six open-source tools that check translation files. They overlap less than their names suggest: some read only JSON, some check your source code rather than the translations, one is built for Rails. Every value below comes from the project’s own README, source code or registry page.
We make Shipi18n, one of the six. Last verified 4 October 2026.
| Shipi18n | i18n-check | i18n-tasks | i18next-cli | i18n-validate | LocaleGuard | |
|---|---|---|---|---|---|---|
| Placeholder parity between locales | Yes — ICU, {{i18next}}, %{rails}, %(python)s, printf, %@ | Yes — ICU and i18next messages parsed and compared | Yes, in health by default — Ruby %{name} syntax only | No — lint compares t() params with the primary locale, not locales with each other | Yes — {x}, {{x}}, %s | Yes — {x} and {{x}}; not a full ICU validator (its README) |
| Plural forms per language (CLDR) | ICU plurals: yes. i18next _one/_other keys: compared with the source only | Only branches present in both files | Yes, using rails-i18n plural rules | Yes — status uses each language’s plural categories | Yes — CLDR v44 plural requirements | vue-i18n a | b only |
| Locale formats | JSON, YAML/Rails, ARB, .xcstrings, Android XML, PO, XLIFF | JSON, YAML | YAML, JSON (Ruby i18n gem projects) | JSON, JSON5, YAML, TS/JS (i18next) | 32 formats claimed, incl. ARB, .xcstrings, Android, PO, XLIFF, RESX, TMX | JSON, YAML, XLIFF, PO |
| Scans your source code | No | Yes — unused/undefined keys (react-intl, i18next, next-intl) | Yes — Ruby/ERB AST scanner, regex for others | Yes — hardcoded strings, interpolation params, key extraction | No | Yes — hardcoded strings, unused/undefined keys (React, Vue, Angular) |
| CI and output | GitHub Action, SARIF, JSON, Docker, pre-commit | Exit code; text output; no Action | Exit code; table, YAML, JSON output; no Action | Exit code (status, lint, extract --ci); no Action | Terminal, JSON, JUnit; no Action, no SARIF | GitHub Action, SARIF, Markdown, JSON |
| Adoption (week of 25 Sep 2026) | ≈560 npm downloads/week (CLI); new | ≈306,000 npm downloads/week | 33.8M total RubyGems downloads; 2,100+ stars | ≈1,010,000 npm downloads/week | ≈8 npm downloads/week; npm still at 0.1.0 | ≈4 npm downloads/week |
| License | Apache-2.0 | MIT | MIT | MIT | MIT (Rust; from i18nagent.ai) | Apache-2.0 |
Which one fits
- Rails app: start with i18n-tasks — it is the native tool and its health command already checks %{name} parity.
- i18next web app: i18next-cli finds hardcoded strings and missing keys; it does not compare placeholders between languages, so pair it with a locale checker.
- react-intl / next-intl, JSON only: i18n-check is the widely used choice and also finds unused keys.
- Mobile or mixed formats (ARB, .xcstrings, Android, gettext, XLIFF) or PR annotations: Shipi18n or i18n-validate; only Shipi18n ships a GitHub Action with SARIF for those formats.
Code scanners and locale checkers answer different questions, so pairing one of each is common. Closer looks: Shipi18n vs i18n-check, vs Lingo.dev.
What the check prints
$ npx @shipi18n/cli check ./locales -s en
🔎 shipi18n check — flat layout, source 'en', 2 target language(s)
✗ de coverage 100.0% 2 error(s), 1 warning(s)
error welcome placeholder-missing — dropped {name}
fix: restore {name} exactly as written in the source
error checkout placeholder-missing — dropped {amount}
fix: rename {betrag} to {amount}
warning checkout placeholder-added — unexpected {betrag}
✓ pl coverage 100.0% 0 error(s), 0 warning(s)
✗ check failed: 2 error(s)No account and no API key. Exit code 1 fails the CI job; the GitHub Action also annotates the PR lines. Quick start
Last verified 4 October 2026 () against these primary sources. Prices and features change; if something here is out of date, open an issue.