Formats
Supported translation file formats
locamorph reads and writes seven translation file formats: JSON,
YAML, Android strings.xml, iOS .strings, Flutter ARB, Java
properties and XLIFF. Import any of them, translate, and export files your toolchain
accepts without a cleanup pass.
Every implemented format ships with a round trip test: what locamorph exports parses back identically, and translator notes travel in both directions.
At a glance
Seven formats, one pipeline
Files enter through uploads, repo syncs, S3 or the CLI, and leave the same ways. The format decides what can be expressed; locamorph maps everything onto one model of keys, values, plurals and notes.
Guarantees
What holds across every format
Exports parse back identically
Each format's exporter is tested against its own parser. A file that leaves locamorph and comes back carries the same keys, values, plurals and notes.
Plural forms are never dropped
Plurals normalize to CLDR categories internally. Android plurals
blocks, ARB ICU messages and XLIFF groups convert without losing a form.
Content based detection
Imports identify the format from the content itself with confidence scoring, so
a YAML file named .txt or an ARB served as JSON still lands right.
Exports are also deterministic. Indentation, key order, nesting and plural style follow the project’s settings rather than whoever exported last, so the same keys always serialize to the same bytes and a translation diff stays down to the strings that changed.
Plurals
One plural, every format
Plurals are where converters usually cheat: they copy the text and drop the forms. locamorph maps every format’s plural syntax onto CLDR categories, so the same plural moves between all of these without losing a form. Each encoding also has its own guide, history and trade offs included.
<plurals name="cart_items">
<item quantity="one">%d article</item>
<item quantity="other">%d articles</item>
</plurals> "cartItems": "{count, plural, one {{count} article} other {{count} articles}}",
"@cartItems": {
"placeholders": { "count": {} }
} "cart": {
"items": "{count, plural, one {# article} other {# articles}}"
} fr:
cart:
items: "{count, plural, one {# article} other {# articles}}" cart.items={count, plural, one {# article} other {# articles}} <group restype="x-gettext-plurals" resname="cart.items">
<trans-unit id="cart.items[one]" resname="cart.items">
<source>%d item</source>
<target state="translated">%d article</target>
</trans-unit>
<trans-unit id="cart.items[other]" resname="cart.items">
<source>%d items</source>
<target state="translated">%d articles</target>
</trans-unit>
</group>
One plural, six spellings, the same CLDR forms underneath. iOS
.strings is missing on purpose: the format has no plural syntax.
Keep going
Where the files come from
Bring the files you already have
Drop a file on a free project and locamorph identifies the format, reads the plurals and keeps the notes. When you export, your toolchain gets exactly the shape it expects.