Skip to main content

Shipi18n vs Phrase

Phrase Strings is the software-localization part of the Phrase platform, a hosted TMS that stores keys and translations and syncs them with your repo and translators. Shipi18n is a linter that checks the locale files in your repo. They do different jobs, and many teams would run both.

We make Shipi18n. Every Phrase fact below links to Phrase’s own pages, last verified 4 October 2026.

Side by side

Shipi18nPhrase
What it isA linter for locale files: checks every translation against the source, locally or in CIHosted platform (Phrase Strings) to store keys and translations and sync them
Dropped or renamed placeholderError, per language — {x}, {{x}}, %{x}, %(x)s, %1$s, %@, ICU arguments“Placeholder usage” QA check; strict mode blocks saving in its editor
Plural formsChecked against each language’s CLDR categories — ICU plurals, i18next _one/_few/_many keys, Rails YAML, Android and .xcstringsNo plural check in its QA-check list
Locale formatsJSON, YAML (incl. Rails), Flutter ARB, Apple .xcstrings, Android strings.xml, gettext PO, XLIFFJSON (incl. i18next), YAML, ARB, .xcstrings, Android XML, PO, XLIFF and more
In CIGitHub Action with SARIF annotations; CLI, Docker image, pre-commit hook, single-file downloadPhrase CLI, setup-cli GitHub Action, GitHub integration
Account or API keyNone (an optional LLM review uses your own key)Account required
PriceFreePlans with Strings seats from $525/mo billed annually; no free plan (14-day trial)
LicenseApache-2.0Proprietary

Where Phrase is stronger

  • Translation memory, in-context editor and over-the-air updates (iOS, Android, Flutter, React Native)
  • Phrase Language AI routes to 30+ machine-translation engines, including LLMs
  • Large integration catalogue

What Phrase doesn’t cover

  • Three QA checks (length, placeholders, term base), enforced in its editor
  • No plural or ICU syntax check listed
  • Doesn’t check files edited in the repo after the sync

Using both

Keep Phrase for translators, memory and workflow. Add shipi18n check in CI to catch what reaches the repo broken — a dropped placeholder, a plural missing a language's forms, invalid ICU — whether it came from the Phrase sync, a developer's hand edit or an AI coding agent.

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.