iOS localization 2026: Guide to .strings, .xcstrings & String Catalogs

Kinga Pomykała
Kinga Pomykała
Last updated: March 31, 202619 min read
iOS localization 2026: Guide to .strings, .xcstrings & String Catalogs

Localizing your iOS app is essential if you want to reach users worldwide. But Apple gives you multiple translation file formats: .strings, .stringsdict, .xcstrings, .xcloc, and .xliff, and it's not always clear which one to use, when, or how they work together. File format decisions like these are part of the broader i18n architectural landscape covered in our complete technical guide to internationalization and software localization.

In this guide, we'll walk through each iOS localization format, explain their differences, show examples, and share best practices.

Why file format choice matters

iOS supports several file formats for localization, each designed for specific scenarios. The choice of file format can impact the ease of translation, the ability to handle complex linguistic features, and the overall efficiency of your localization workflow.

Choosing the right file format isn't just a technical detail:

  • Some formats support pluralization and device-specific variants, others don't.
  • Some formats carry metadata, comments, and translation states, which help translators.
  • Some are better for working with agencies or translation tools.
  • Apple is actively evolving which formats it recommends.
  • SimpleLocalize supports import, export, CLI, API for all major iOS localization formats, which enables automating sync with your builds.

Does Apple impose a specific format?

Apple doesn’t force you to use a single format, but there are defaults that depend on your tools and iOS version:

Historically (.strings + .stringsdict):

  • .strings files were the standard. If you localized a project in older Xcode versions, Apple generated Localizable.strings by default.
  • Pluralization was handled separately via .stringsdict files.

Today (.xcstrings):

  • Since Xcode 15, the default when you add a new localized string in the String Catalog editor is .xcstrings.
  • This format combines .strings and .stringsdict into a single structured file, with added support for metadata and translation state.

Exchange formats (.xcloc & .xliff):

  • .xcloc and .xliff are not default storage formats in your repo, they are used when exporting/importing translations for collaboration with agencies

In practice, Apple will load translations from any of these supported formats as long as the files are placed in the correct *.lproj language folder inside your app bundle.

  • If your project contains only .strings, iOS will load them.
  • If it contains .xcstrings, iOS will load those.
  • You can use both formats side by side, which makes gradual migration possible.

Apple is clearly nudging developers toward string catalogs (.xcstrings), but older formats remain supported.

Comparison of iOS translation formats

Here's a summary of the main formats you'll see, what they support, and when to use them. Later sections deepen those details.

FormatStructurePlural supportMetadata / contextBest use case
.stringsKey-value pairsNoNoBasic UI strings, small apps, legacy projects
.stringsdictXMLYesLimitedPlurals, device-specific variants, complex text
.xcstringsJSON-likeYesYes (comments, state, variants)Modern projects, recommended going forward
.xclocCatalog of .xliff + metadataYesYesExport/import full localization projects
.xliffStandard XMLYesYesCollaboration with agencies, translators

.strings: The classic format

.strings files are simple key-value pairs:

// English
"welcome_message" = "Welcome to the app!";
"logout" = "Log out";
"items_count" = "You have %d items.";

// French
"welcome_message" = "Bienvenue dans l'application !";
"logout" = "Se déconnecter";
"items_count" = "Vous avez %d éléments.";

About:

  • Plain text key-value pairs, e.g. "key" = "Translated text";
  • Stored inside *.lproj folders (e.g., en.lproj/Localizable.strings).
  • Classic format for static strings in iOS / macOS.

Limitations:

  • No pluralization.
  • No metadata or context for translators.
  • No built-in device variants.

Use .strings if you are maintaining a legacy app or just need quick, simple localization.

SimpleLocalize support:

You can manage .strings files directly in SimpleLocalize:

simplelocalize upload --apiKey <PROJECT_API_KEY> \
  --uploadFormat localizable-strings \
  --uploadPath ./{lang}/Localizable.strings

  simplelocalize download --apiKey <PROJECT_API_KEY> \
  --downloadFormat localizable-strings \
  --downloadPath ./{lang}/Localizable.strings
  • Import/export .strings files straight from the translation editor.
  • Automate sync with the CLI, REST API, or set up a GitHub integration to keep translations in step with your repository.
Uploading and downloading .strings files in SimpleLocalize's translation editor

Check out our docs for more details regarding .strings support in SimpleLocalize.

.stringsdict: Handling plurals and variants

.stringsdict files are XML-based and support pluralization and device-specific variants:

<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
    <key>items_count</key>
    <dict>
    <!-- Pluralization example -->
        <key>NSStringLocalizedFormatKey</key>
        <string>%#@items@</string>
        <key>items</key>
        <dict>
            <key>NSStringFormatSpecTypeKey</key>
            <string>NSStringPluralRuleType</string>
            <key>NSStringFormatValueTypeKey</key>
            <string>d</string>
            <key>one</key>
            <string>You have %d item.</string>
            <key>other</key>
            <string>You have %d items.</string>
        </dict>
    </dict>
    <!-- Device specific example -->
    <key>user_instructions</key>
    <dict>
        <key>NSStringDeviceSpecificRuleType</key>
        <dict>
            <key>iphone</key>
            <string>Tap here</string>
            <key>mac</key>
            <string>Click here</string>
            <key>appletv</key>
            <string>Press here</string>
        </dict>
    </dict>
</dict>
</plist>

About:

  • XML format that supports pluralization rules and device-specific variants.
  • Must be paired with a .strings file for non-plural text.

Usage:

  • For strings that vary depending on count (plural forms).
  • For device-specific versions (e.g. different wording or instructions on Mac vs iPhone).

SimpleLocalize support:

You can manage .stringsdict files directly in SimpleLocalize:

simplelocalize upload --apiKey <PROJECT_API_KEY> \
  --uploadFormat localizable-strings-dict \
  --uploadPath ./{lang}/Localizable.stringsdict
  • Import/Export: Fully supported. Upload .stringsdict files directly from the translation editor or via CLI/API.
  • In the translation editor, plural forms will be shown as separate translation keys (e.g. items_count.one, items_count.other).
.stringsdict file upload example

Check out our docs for more details regarding .stringsdict support in SimpleLocalize.

.xcstrings: The modern string catalog

.xcstrings files are JSON-like and combine the features of .strings and .stringsdict, with added metadata:

{
  "version": "1.0",
  "sourceLanguage" : "en",
  "strings" : {
    "hello_world" : {
      "shouldTranslate": true,
      "comment" : "Here is a comment for the translator",
      "extractionState" : "manual",
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Hello World"
          }
        },
        "fr" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Bonjour le monde"
          }
        }
      }
    },
    "items_count" : {
      "shouldTranslate": true,
      "comment" : "Number of items in the cart",
      "extractionState" : "manual",
      "localizations" : {
        "en" : {
          "variations" : {
            "plural" : {
              "one" : {
                "stringUnit" : {
                  "state" : "translated",
                  "value" : "You have %lld item."
                }
              },
              "other" : {
                "stringUnit" : {
                  "state" : "translated",
                  "value" : "You have %lld items."
                }
              }
            }
          }
        }
      }
    }
  }
}

About:

  • Apple's recommended format starting with Xcode 15.
  • JSON-like structure that replaces .strings + .stringsdict.
  • Supports pluralization, device variants, comments, and translation state.

Why use it:

  • Modern, structured, future-proof.
  • Easier to manage in Xcode's GUI.
  • Built-in support for plural forms and device variants.

SimpleLocalize support:

String catalogs are fully supported:

# Upload translations to SimpleLocalize
simplelocalize upload --apiKey <PROJECT_API_KEY> \
  --uploadFormat localizable-xcstrings \
  --uploadPath ./Localizable.xcstrings

# Download translations from SimpleLocalize
simplelocalize download --apiKey <PROJECT_API_KEY> \
  --downloadFormat localizable-xcstrings \
  --downloadPath ./Localizable.xcstrings
  • Import and export just one .xcstrings file per language or multiple files (namespaces).
  • Manage all translations centrally in the translation editor, add new languages, and run auto-translation and quality checks.
  • Use CLI, API, or GitHub integration for continuous localization.
  • Enable universal placeholders (--uploadOptions UNIVERSAL_PLACEHOLDERS) to convert iOS-native format specifiers like %@ and %lld into platform-independent placeholders (useful if you manage both iOS and Android translations).

CI/CD pattern: upload on push, download into build

# In your CI pipeline (e.g., GitHub Actions)
# Step 1: Upload source strings after merge to main
simplelocalize upload --apiKey <PROJECT_API_KEY> \
  --uploadFormat localizable-xcstrings \
  --uploadPath ./Localizable.xcstrings \
  --overwrite

# Step 2: Download latest translations before build
simplelocalize download --apiKey <PROJECT_API_KEY> \
  --downloadFormat localizable-xcstrings \
  --downloadPath ./Localizable.xcstrings

Check out our docs for more details regarding .xcstrings support in SimpleLocalize.

Translation workflow with Localizable XC Strings

Xcode 26 note: Xcode 26 (announced at WWDC25) introduces version 1.1 of the .xcstrings format with automatic AI-generated context comments. This means Xcode can now auto-generate translator-facing notes based on how strings are used in your code. SimpleLocalize will import and preserve these comments when you upload your .xcstrings file.

.xcloc: Localization catalogs

.xcloc files are packages that contain .xliff localization files along with metadata about the localization project.

MyApp.xcloc/
  ├── Contents.json
  └── Localizations/
        ├── en.xliff
        ├── fr.xliff
        └── de.xliff

About:

  • A folder (bundle) containing .xliff files and a Contents.json metadata file.
  • Generated by Xcode when you use Export for Localization.

Use case:

  • Full localization handoff to translators.
  • Best when working with external agencies or teams that use .xliff.

Learn more about .xcloc file format.

.xliff: The exchange format

.xliff (XML Localization Interchange File Format) is a standard XML-based format for exchanging localization data between different tools.

<?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.2">
  <file source-language="en" target-language="fr" datatype="plaintext" original="Localizable.strings">
    <body>
      <trans-unit id="hello_world">
        <source>Hello World</source>
        <target>Bonjour le monde</target>
        <note>Here is a comment for the translator</note>
      </trans-unit>
      <trans-unit id="items_count">
        <source>You have %d items.</source>
        <target>Vous avez %d articles.</target>
      </trans-unit>
    </body>
  </file>
</xliff>

About:

  • Industry-standard XML format for exchanging translations.
  • Widely supported outside Apple’s ecosystem.
  • Can represent complex structures, including plural forms and context.

Use .xliff if you need to collaborate with translation agencies or tools that don’t use Xcode.

SimpleLocalize support:

You can import and export .xliff files directly in SimpleLocalize, from the translation editor or via CLI/API.

simplelocalize upload \
  --apiKey PROJECT_API_KEY \
  --uploadLanguageKey en \
  --uploadFormat xliff:1.2 \
  --uploadPath ./en.xliff

Check out the details in our docs regarding .xliff support in SimpleLocalize or read our dedicated blog post about XLIFF files.

.xliff translation file management example

How to migrate from .strings to .xcstrings

If you have an existing project using .strings and .stringsdict files, Xcode makes it easy to migrate to the modern .xcstrings format.

Step-by-step migration in Xcode

  1. Open your project in Xcode 15 or later.
  2. Select your Localizable.strings file in the Project Navigator.
  3. Go to Editor → Convert to String Catalog.
  4. Xcode will show a confirmation dialog listing the files to convert. Click Convert.
  5. Xcode creates a new Localizable.xcstrings file and migrates all your keys, values, and comments.
  6. If you also have a Localizable.stringsdict file, Xcode will merge pluralization rules into the new catalog automatically.
  7. Delete the old .strings and .stringsdict files after verifying the migration.
// Before migration: two separate files
// en.lproj/Localizable.strings
"welcome_message" = "Welcome!";
"items_count" = "You have %d items.";

// en.lproj/Localizable.stringsdict
// (XML with NSStringPluralRuleType for items_count)

// After migration: single Localizable.xcstrings file
// Contains both simple strings and plural rules in one structured JSON file.

Tip: You can convert individual .strings files or convert all at once. Xcode preserves your existing translations, comments, and plural forms during the migration.

What to watch out for

  • Custom .strings filenames: If you use files other than Localizable.strings (e.g., Settings.strings), each one converts to its own .xcstrings catalog.
  • Build settings: After conversion, verify that the new .xcstrings file is included in your target's resources.
  • Source control: Commit the new .xcstrings file and remove the old .strings/.stringsdict files in the same commit.
  • CI/CD pipelines: Update your localization scripts to use localizable-xcstrings format instead of localizable-strings.

If you're using SimpleLocalize, update your CLI commands after migration:

# Before (old format)
simplelocalize upload --apiKey <PROJECT_API_KEY> \
  --uploadFormat localizable-strings \
  --uploadPath ./{lang}/Localizable.strings

# After (new format)
simplelocalize upload --apiKey <PROJECT_API_KEY> \
  --uploadFormat localizable-xcstrings \
  --uploadPath ./Localizable.xcstrings

Multiple string catalogs and namespacing

While the examples above show a single Localizable.xcstrings file, real-world projects often split translations into multiple catalogs organized by feature or module. This is especially useful for large apps where a single file becomes hard to manage.

Why use multiple catalogs?

  • Feature isolation: Each team or module owns its own translations (e.g., Settings.xcstrings, Onboarding.xcstrings, Checkout.xcstrings).
  • Faster builds: Xcode only recompiles catalogs that changed.
  • Cleaner diffs: Smaller files mean fewer merge conflicts.
  • Lazy loading: Load translations on demand for features that aren't always used.

How it works in Xcode

Create additional .xcstrings files in your project:

MyApp/
├── Localizable.xcstrings          # General / shared strings
├── Settings.xcstrings              # Settings module strings
├── Onboarding.xcstrings            # Onboarding flow strings
└── Checkout.xcstrings              # Checkout flow strings

In Swift, reference strings from a specific catalog using the table parameter:

// Load from default Localizable.xcstrings
Text("welcome_message")

// Load from Settings.xcstrings
Text("notifications_label", tableName: "Settings")

// Load from Onboarding.xcstrings
String(localized: "step_1_title", table: "Onboarding")

Syncing multiple catalogs with SimpleLocalize

SimpleLocalize maps each .xcstrings file to a namespace, so you can manage them all in one project:

# Upload all catalogs (each file becomes a namespace)
simplelocalize upload --apiKey <PROJECT_API_KEY> \
  --overwrite \
  --uploadFormat localizable-xcstrings \
  --uploadPath ./Localizable-{ns}.xcstrings
  --overwrite

# Download all catalogs
simplelocalize download --apiKey <PROJECT_API_KEY> \
  --downloadFormat localizable-xcstrings \
  --downloadPath ./Localizable-{ns}.strings

The {ns} placeholder in the path automatically maps filenames to namespaces. For example, Localizable-settings.xcstrings becomes the Settings namespace in SimpleLocalize, and Localizable-onboarding.xcstrings becomes the Onboarding namespace.

Learn more about namespaces in SimpleLocalize and how they help you organize translations at scale.

Managing iOS translations with SimpleLocalize

Manually handling multiple iOS localization formats and translation updates can lead to errors, inconsistencies, and wasted time. SimpleLocalize TMS makes the translation management easier by allowing you to:

  • Import/export of all iOS formats via CLI, REST API, or GitHub integration.
  • Centralize all your iOS translation files in one place.
  • Provide translators with context, comments, and plural forms.
  • Collaborate with teams and agencies.
  • Auto-translate and run quality checks.
  • Automate review process and translation workflows.
  • Keep translations in sync with your codebase.

Check some examples of AI-powered localization workflow automation with SimpleLocalize.

Best practices for iOS localization

While iOS provides flexibility in localization formats, following best practices can help to improve your workflow and ensure high-quality translations:

  • Use keys, not hardcoded strings. Make them consistent and descriptive.
  • Prefer .xcstrings for new projects.
  • For large projects, consider namespacing your strings into multiple files.
  • Store pluralization in .stringsdict or .xcstrings.
  • Provide context and comments for translators.
  • Regularly review translations and run quality checks.
  • Export .xcloc or .xliff when working with agencies.
  • Automate with SimpleLocalize to avoid manual mistakes.

If you are using .strings, keep one Localizable.strings per language. For new projects, prefer .xcstrings catalogs, one per language.

Final thoughts

Apple's localization formats have evolved from .strings to .xcstrings, with .xcloc and .xliff for translation exchange. While multiple formats are supported, Apple is clearly moving toward string catalogs as the future of iOS localization.

With SimpleLocalize, you don't have to worry about file quirks. Upload any format, manage translations in one place, and sync them back to your app with a single command.

Ready to simplify your iOS localization workflow? Start with SimpleLocalize.

Related reading: For a deep dive into the .xcstrings format, including advanced pluralization, device variants, substitutions, and CI/CD automation, check out our complete guide to Xcode String Catalogs (.xcstrings).

FAQ

Is Localizable.strings and .strings the same thing?
Yes, Localizable.strings is just a common filename convention for .strings files. You can name your .strings files anything, but Localizable.strings is the default name Xcode uses when you add localization.
Can I mix .strings and .xcstrings in the same app?
Yes. iOS will load translations from both as long as the files are placed in the correct *.lproj folders. This allows you to migrate gradually instead of all at once.
Do I still need .stringsdict if I use .xcstrings?
No, .xcstrings supports pluralization and device variants natively, so you can consolidate everything into a single file per language.
How do I choose between .xcloc and .xliff?
Use .xcloc when exporting/importing full localization projects from Xcode, especially when working with agencies. Use .xliff if you need a more universal format that works across different tools.
Can SimpleLocalize automatically sync translations with my repository?
Yes. Besides manual import/export, you can use the CLI for batch upload/download, call the REST API for automation, or set up the GitHub integration for continuous localization where every commit can trigger a sync of translations.
What if I only need to translate a few strings?
That's fine. You can import just one .strings or .xcstrings file into SimpleLocalize, add a new language, run auto-translation, and export it back without touching your whole project.
Will Apple remove support for .strings files?
Not in the near future. .strings files are still widely used and supported. However, Apple is clearly moving toward .xcstrings catalogs as the long-term format, so it's a good idea to adopt them for new projects.
How do I migrate from .strings to .xcstrings?
In Xcode 15 or later, select your .strings file and go to Editor → Convert to String Catalog. Xcode will create a new .xcstrings file and migrate all your keys, values, comments, and plural forms automatically.
Can I use multiple .xcstrings files in one project?
Yes. You can split translations into multiple catalogs by feature or module (e.g., Settings.xcstrings, Onboarding.xcstrings). In Swift, use the tableName parameter to load strings from a specific catalog. SimpleLocalize maps each file to a namespace for centralized management.
Kinga Pomykała
Kinga Pomykała
Content creator of SimpleLocalize

Get started with SimpleLocalize

  • All-in-one localization platform
  • Web-based translation editor for your team
  • Auto-translation, QA-checks, AI and more
  • See how easily you can start localizing your product.
  • Powerful API, hosting, integrations and developer tools
  • Unmatched customer support
Start for free
No credit card required5-minute setup
"The product
and support
are fantastic."
Laars Buur|CTO
"The support is
blazing fast,
thank you Jakub!"
Stefan|Developer
"Interface that
makes any dev
feel at home!"
Dario De Cianni|CTO
"Excellent app,
saves my time
and money"
Dmitry Melnik|Developer