Convert between 32+ i18n file formats. Android XML, iOS Strings, XLIFF, PO, JSON, YAML, and more. Lossless where possible, with clear data loss warnings when not.
Every platform speaks a different translation format. Android uses strings.xml. iOS uses .strings and .stringsdict. Web apps use JSON or YAML. Translators and TMS platforms want XLIFF or PO. When you need to share strings between platforms, you end up copy-pasting between formats, writing one-off scripts, or manually restructuring files. It's tedious, error-prone, and breaks every time a new format shows up.
i18n-convert is a single CLI tool that converts between 32+ i18n file formats. It auto-detects the input format, preserves as much structure as possible, and warns you when a conversion would lose data (like plurals in CSV).
# Auto-detect input format, convert to Android XML
i18n-convert en.json --to android-xml -o strings.xml
# iOS Strings to Gettext PO
i18n-convert Localizable.strings --to po -o messages.po
# XLIFF to Rails YAML
i18n-convert translations.xliff --to yaml-rails -o en.yml
# Pipe to stdout
i18n-convert messages.po --to jsonInput format is detected automatically from file extension and content. No flags needed.
Metadata, comments, and plural forms are preserved when the target format supports them.
When a conversion would lose information, you get explicit warnings before any file is written.
Install via npm for the easiest setup, Homebrew on macOS, or build from source with Cargo.
npm install -g @i18n-agent/i18n-convertMost teams need a handful of conversions repeatedly: JSON to Android XML for mobile, PO to JSON for web, XLIFF round-trips for translator handoff. Here are some common patterns.
# Convert all PO files to JSON
for f in locales/*.po; do
i18n-convert "$f" --to json -o "${f%.po}.json"
done
# Convert entire directory
i18n-convert locales/ --to json --out-dir locales-json/i18n-convert supports 32+ formats across mobile, web, localization standards, and data exchange categories.
| Format | Extension | Flag |
|---|---|---|
| Android XML | .xml | --to android-xml |
| iOS Strings | .strings | --to ios-strings |
| iOS Stringsdict | .stringsdict | --to ios-stringsdict |
| Flutter ARB | .arb | --to arb |
| Format | Extension | Flag |
|---|---|---|
| JSON (flat) | .json | --to json |
| JSON (nested) | .json | --to json-nested |
| YAML | .yml | --to yaml |
| YAML (Rails) | .yml | --to yaml-rails |
| Properties | .properties | --to properties |
| Format | Extension | Flag |
|---|---|---|
| XLIFF 1.2 | .xlf | --to xliff |
| XLIFF 2.0 | .xlf | --to xliff-2 |
| Gettext PO | .po | --to po |
| Gettext POT | .pot | --to pot |
| TMX | .tmx | --to tmx |
| TBX | .tbx | --to tbx |
| Format | Extension | Flag |
|---|---|---|
| CSV | .csv | --to csv |
| TSV | .tsv | --to tsv |
| Excel | .xlsx | --to xlsx |
Not all formats are equal. XLIFF supports notes, contexts, and plural forms. CSV supports none of those. When you convert from a rich format to a simpler one, i18n-convert tells you exactly what will be lost.
$ i18n-convert plurals.po --to csv
Data loss warnings:
[ERROR] 3 entries use plurals (not supported by CSV)
Proceed? [y/N]
# Skip prompts
i18n-convert plurals.po --to csv --force
# Preview warnings without writing
i18n-convert plurals.po --to csv --dry-runAutomate format synchronization in your CI/CD pipeline. When your source translation file changes, automatically regenerate all derived formats so mobile, web, and translator files stay in sync.
# .github/workflows/format-sync.yml
name: Sync Translation Formats
on:
push:
branches: [main]
paths: ['locales/en.json']
jobs:
sync-formats:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install i18n-convert
run: npm install -g @i18n-agent/i18n-convert
- name: Convert JSON to Android XML
run: i18n-convert locales/en.json --to android-xml -o android/res/values/strings.xml
- name: Convert JSON to iOS Strings
run: i18n-convert locales/en.json --to ios-strings -o ios/en.lproj/Localizable.strings
- name: Commit synced formats
run: |
git config user.name "github-actions"
git config user.email "[email protected]"
git add android/ ios/
git diff --cached --quiet || git commit -m "chore: sync translation formats"
git pushDrop your translation file here
JSON, YAML, PO, XML, CSV, Markdown, Properties
or click to browse
Target languages