i18n-convert

May 20, 2026 · View on GitHub

CI license

Cross-platform localization file format converter — 32 formats, zero dependencies beyond the binary.

The Problem

Every platform has its own localization format. Moving translations between Android XML, iOS Strings, XLIFF, PO, JSON, YAML, and 26 other formats means writing custom scripts, losing metadata, or paying for a SaaS tool.

The Solution

One binary. Any format in, any format out. Lossless round-trips where possible, data loss warnings where not.

i18n-convert messages.json --to android-xml -o strings.xml

Need to translate, not just convert?

i18n-convert changes the shape of your localization files. If you also need to translate their content with AI quality, i18nagent.ai is the MCP server we built for that — plug it into Claude or another MCP-aware AI tool and translate across the same 32 formats with multi-model AI quality.

Same author. Same audience. Same formats.

Installation

npm install -g @i18n-agent/i18n-convert

Homebrew

brew tap i18n-agent/tap
brew install i18n-convert

Download binary

Download the latest release for your platform from GitHub Releases.

macOS (Apple Silicon):

curl -L https://github.com/i18n-agent/i18n-convert/releases/latest/download/i18n-convert-aarch64-apple-darwin.tar.gz | tar xz
sudo mv i18n-convert /usr/local/bin/

macOS (Intel):

curl -L https://github.com/i18n-agent/i18n-convert/releases/latest/download/i18n-convert-x86_64-apple-darwin.tar.gz | tar xz
sudo mv i18n-convert /usr/local/bin/

Linux (x64):

curl -L https://github.com/i18n-agent/i18n-convert/releases/latest/download/i18n-convert-x86_64-unknown-linux-gnu.tar.gz | tar xz
sudo mv i18n-convert /usr/local/bin/

Linux (ARM):

curl -L https://github.com/i18n-agent/i18n-convert/releases/latest/download/i18n-convert-aarch64-unknown-linux-gnu.tar.gz | tar xz
sudo mv i18n-convert /usr/local/bin/

Windows:

Download i18n-convert-x86_64-pc-windows-msvc.zip from Releases, extract, and add to your PATH.

Build from source

git clone https://github.com/i18n-agent/i18n-convert.git
cd i18n-convert
cargo build --release
# Binary at target/release/i18n-convert

Usage

Basic conversion

# Auto-detect input format, convert to Android XML
i18n-convert en.json --to android-xml -o strings.xml

# Convert iOS strings to PO
i18n-convert Localizable.strings --to po -o messages.po

# Convert XLIFF to YAML
i18n-convert translations.xliff --to yaml-rails -o en.yml

# Output to stdout (pipe-friendly)
i18n-convert messages.po --to json

Data loss warnings

When converting between formats with different capabilities, i18n-convert warns you before data is lost:

$ i18n-convert plurals.po --to csv
Data loss warnings:
  [ERROR] 3 entries use plurals (not supported by CSV)

Proceed? [y/N]

Use --force to skip prompts, or --dry-run to see warnings without writing.

List all formats

i18n-convert --list-formats

CLI flags

FlagDescription
--to <format>Target format (required)
-o <file>Output file (default: stdout)
--forceSkip data loss confirmation
--dry-runShow warnings without writing
--verboseShow conversion details
--list-formatsList all supported formats

Supported Formats (32)

Mobile & Desktop

FormatIDExtensions
Android XMLandroid-xml.xml
Xcode String Catalogxcstrings.xcstrings
iOS Stringsios-strings.strings
iOS Stringsdictstringsdict.stringsdict
iOS Property Listios-plist.plist
Flutter ARBarb.arb
Qt Linguistqt.ts

Web & Frameworks

FormatIDExtensions
Structured JSONjson.json
i18next JSONi18next.json
JSON5json5.json5
HJSONhjson.hjson
YAML (Rails)yaml-rails.yml .yaml
YAML (Plain)yaml-plain.yml .yaml
JavaScriptjavascript.js
TypeScripttypescript.ts
PHP/Laravelphp-laravel.php
NEONneon.neon

Standards & Exchange

FormatIDExtensions
XLIFF 1.2xliff.xliff .xlf
XLIFF 2.0xliff2.xliff .xlf
Gettext POpo.po .pot
TMXtmx.tmx
.NET RESXresx.resx
Java Propertiesjava-properties.properties

Data & Other

FormatIDExtensions
CSVcsv.csv .tsv
Excelexcel.xlsx .xls
TOMLtoml.toml
INIini.ini
SRT Subtitlessrt.srt
Markdownmarkdown.md
Plain Textplain-text.txt

Vendor-Specific

FormatIDExtensions
iSpring Suite XLIFFispring-xliff.xliff .xlf
Adobe Captivate XMLcaptivate-xml.xml

Architecture

All conversions go through a central Intermediate Representation (IR):

Source Format  →  Parser  →  IR (I18nResource)  →  Writer  →  Target Format

The IR preserves:

  • Translation entries with keys and values
  • Plurals (zero/one/two/few/many/other)
  • Arrays, select/gender, multi-variable plurals
  • Comments with roles (developer, translator, extracted)
  • Source strings, translation state, max-width constraints
  • Format-specific extensions for lossless round-trips

Adding a New Format

  1. Add the format ID to src/ir/resource.rs (FormatId enum)

  2. Add the format extension to src/ir/extensions.rs (FormatExtension enum + struct)

  3. Create the parser/writer at src/formats/your_format.rs:

use super::*;

pub struct Parser;
pub struct Writer;

impl FormatParser for Parser {
    fn detect(&self, extension: &str, content: &[u8]) -> Confidence {
        // Return Definite/High/Low/None based on extension + content inspection
    }

    fn parse(&self, content: &[u8]) -> Result<I18nResource, ParseError> {
        // Parse bytes into IR
    }

    fn capabilities(&self) -> FormatCapabilities {
        // Declare what your format supports
        FormatCapabilities {
            plurals: false,
            nested_keys: true,
            comments: false,
            // ... (14 capability flags total)
            ..Default::default()
        }
    }
}

impl FormatWriter for Writer {
    fn write(&self, resource: &I18nResource) -> Result<Vec<u8>, WriteError> {
        // Convert IR back to bytes
    }

    fn capabilities(&self) -> FormatCapabilities {
        Parser.capabilities()
    }
}
  1. Register it in src/formats/mod.rs:
pub mod your_format;

// In FormatRegistry::new():
Self::register(
    &mut formats,
    "your-format",
    "Your Format Name",
    &[".ext"],
    your_format::Parser,
    your_format::Writer,
);
  1. Add tests at tests/roundtrip_your_format.rs with fixtures in tests/fixtures/your_format/

  2. Run the full suite:

cargo fmt
cargo clippy -- -D warnings
cargo test

Contributing

  • Open issues for bugs or feature requests.
  • PRs welcome, especially for adding new formats.
  • Run cargo test before submitting.

License

MIT License - see LICENSE file.

Built by i18nagent.ai