Localize Your App

.strings vs .xcstrings vs strings.xml vs .arb: Localization File Formats Explained

Every mobile ecosystem invented its own localization file format, and each encodes the same three things differently: key–value strings, placeholders, and plurals. Here's a field guide to the five formats that matter — .strings, .xcstrings, strings.xml, .arb, and i18n JSON — plus how to convert between them without losing plurals or placeholders.

This guide is about the files themselves. For the wider decision — which languages to ship, what a translation pass costs, and what order to do it in — start with the complete app localization guide.

The five formats at a glance

FormatPlatformPlaceholdersPlurals
.stringsiOS / macOS (legacy)%@ %lld %1$@Separate .stringsdict
.xcstringsiOS / macOS (modern)%@ %lldBuilt-in variants
strings.xmlAndroid%1$s %2$d<plurals> blocks
.arbFlutter{name} ICUICU {n, plural, …}
i18n JSONReact Native / web{{var}}Key suffixes (_one, _other)

What each format gets right (and wrong)

.strings — simple, but plurals live elsewhere

Flat key–value pairs, C-style escapes. Easy to parse, but plural logic requires a parallel .stringsdict, and multi-language apps mean parallel files per locale. Full walkthrough: translating .strings files.

.xcstrings — one JSON file, all languages

Apple's current format merges every language and plural variant into a single catalog Xcode maintains automatically. Best-in-class for iOS; almost nothing outside Xcode parses it correctly. Details: translating String Catalogs.

strings.xml — explicit and verbose

XML with positional format args and per-language values-xx folders. Entities (&amp;) and embedded HTML are the classic translation casualties. Details: translating strings.xml.

.arb — ICU MessageFormat in JSON

The most expressive plural/select syntax of the group, and the most fragile: one ICU typo fails Flutter codegen. Details: translating .arb files.

i18n JSON — a convention, not a standard

Nested keys, double-brace interpolation, plural key suffixes that vary by library configuration. Structure preservation is everything. Details: React Native localization.

Converting between formats

Cross-format conversion is where hand-rolled scripts die, because the plural models don't map 1:1 — an ICU plural block must become a .stringsdict-style variant set or an i18next suffix family, per language. Localize Your App treats formats as interchangeable views over the same strings: upload any supported format, translate into any of 50 languages, and export to any other supported format. The practical wins:

  • Migrate legacy .strings to a modern .xcstrings catalog in one pass.
  • Ship an iOS and Android app from one uploaded string set — same translations, same glossary, both native formats out.
  • Placeholders are converted structurally (%1$s ↔ ICU ↔ %@), not string-replaced, and every output is validated before download.

Whatever format you're in today, it stops being a lock-in decision — which changes the cost math for shipping more platforms.

Everything in Localization file formats

Every mobile ecosystem invented its own string format. How each one handles plurals and placeholders, and how to translate it without breaking either.

Ship your app in 50 languages by tonight

Upload your localization file, review side by side, download ready-to-import files for every language. One-time credits from $9 — no subscription.

No subscription. Credits never expire.

Related guides