# What Is the .xcstrings Format? Xcode String Catalogs

> String Catalogs (.xcstrings) are Apple''s localization format: one JSON file holding every locale plus a per-string translation state. How to edit it.

Source: https://stringlane.app/docs/what-is-xcstrings
Last updated: 2026-08-19

`.xcstrings` is the file extension for **String Catalogs**, the localization format Apple introduced at WWDC 2023 to replace the older `.strings` and `.stringsdict` files. A String Catalog is a single JSON file that holds every locale for a target, plus a translation **state** for each string, so Xcode can show you, per language, what is new, what needs review, and what is done.

## What it replaces

The classic Apple approach split localization across formats:

- `Localizable.strings`: one file per locale, simple `"key" = "value";` pairs.
- `Localizable.stringsdict`: a separate XML plist just for plurals.

String Catalogs fold all of that into one `.xcstrings` file per string table, with plural and device variations expressed inline. Xcode extracts strings into it automatically at build time.

## What a String Catalog contains

The file is JSON keyed by source string. Each entry stores its localizations and, critically, a `state` for every language:

- **`new`**: extracted but not yet translated.
- **`needs_review`**: translation exists but is flagged for a second look.
- **`translated`**: done.

It also tracks strings marked `shouldTranslate: false`, system-managed text that should be left alone, and a `extractionState` that records whether a string is still present in code.

## Why the state model matters

The per-string state is the feature, and it is also the thing hand-editing the JSON gets wrong. Edit a value in a text editor and the surrounding `state` does not update, so Xcode's "what still needs translating" view drifts out of sync with reality. Multiply that across a few hundred strings and several locales and the catalog becomes untrustworthy.

## How StringLane works with .xcstrings

StringLane reads and writes `.xcstrings` natively. It auto-detects the format by extension, loads every locale from the single file, and shows them side-by-side like any other project. A string Xcode has extracted but nobody has translated carries a grey **New** badge. When you edit and save, StringLane updates the state automatically (a non-empty value becomes `translated`, an empty one reverts to `new`) and locks `shouldTranslate: false` strings against editing. Adding a locale merges into the existing file rather than creating a new one, so the catalog stays canonical.

![The settingsAppearance key from a String Catalog: English translated, German empty with a grey NEW badge and a red MISSING badge, French filled in, and Japanese missing](/docs-screenshots/xcstrings-translation-state.webp)

Two caveats on `needs_review` specifically, since it is the state that carries the most information. Catalogs spell it with an underscore and StringLane's badge matches a hyphenated spelling, so a string awaiting review currently shows no badge — in the screenshot above, French is `needs_review` and looks the same as a finished translation. Saving also recomputes every string's state from whether it has a value, which relabels `needs_review` as `translated` across the whole catalog. Until both are fixed, treat Xcode as the authority on review state.

## Next steps

- **[xcstrings editor](/xcstrings-editor)**: what StringLane validates in a String Catalog, and how translation state is kept in sync.
- **[How to Use the Format Editor](/docs/use-format-editor)**: format-specific editing for iOS, Android, and i18next projects.
- **[How to Open a Localization Project](/docs/open-a-project)**: auto-detection and what StringLane loads.
- **[How to Add a New Locale](/docs/add-a-locale)**: add a language column from a preset.

## Frequently asked questions

### What replaced .strings and .stringsdict?

String Catalogs (.xcstrings), introduced with Xcode 15. One catalog replaces the whole set of per-language .strings files plus the separate .stringsdict for plurals, holding every locale and every plural form in a single JSON file.

### Do I have to migrate from .strings to .xcstrings?

No. Xcode still builds .strings and .stringsdict, and plenty of shipping apps stay on them. Migration is worth it mainly for the per-string translation state, which is the part that tells you what has actually been translated.

### What do the new, needs_review and translated states mean?

They are Xcode's record of how current each translation is. new means the string was extracted but never translated; needs_review means the source string changed after translation, so the existing translation may no longer be correct; translated means it is current. needs_review is the one that catches drift.

### Can I edit an .xcstrings file outside Xcode?

Yes — it is JSON. In practice the nesting is deep enough that hand-editing is error-prone, and it is easy to leave the translation state saying something the content no longer supports. StringLane edits the catalog directly and keeps the state in step as you type.
