XCStrings Translator
Translate Apple's Localizable.xcstrings files using AI. Supports Claude, GPT, and Gemini.
xcstrings translate Localizable.xcstrings -l fr,es,it,ja,ko
Features
- Multi-provider - Choose Claude, GPT, or Gemini based on cost/quality needs
- Context-aware - Uses existing translations to understand meaning and tone
- Format-safe - Preserves
%@,%lld,%1$@and other specifiers - 35+ languages - All major App Store locales
- Recursive - Point at a directory to translate every nested
.xcstringsfile - Cost estimation - Preview costs before translating
- Validation - Detect missing translations and format mismatches
Quick Start
# Install
pip install xcstrings-translator
# Set API key (pick one)
export ANTHROPIC_API_KEY=sk-... # Claude
export OPENAI_API_KEY=sk-... # GPT
export GOOGLE_API_KEY=... # Gemini
export OPENROUTER_API_KEY=sk-or-... # OpenRouter (any vendor)
# Translate
xcstrings translate Localizable.xcstrings -l fr,de,ja
Models
| Model | Provider | Cost/1M tokens | Best for |
|---|---|---|---|
haiku |
Anthropic | $1 in / $5 out | Fast iteration |
sonnet |
Anthropic | $3 in / $15 out | Recommended (default) |
opus |
Anthropic | $5 in / $25 out | Highest quality |
gpt-5.4-nano |
OpenAI | $0.20 in / $1.25 out | Cheapest |
gpt-5.4 |
OpenAI | $2.50 in / $15 out | Quality |
gpt-5.5 |
OpenAI | $5 in / $30 out | Flagship |
gemini-3.5-flash |
$1.50 in / $9 out | Fast & balanced | |
gemini-3.1-pro |
$2 in / $12 out | Quality |
Older aliases still work:
gpt-5,gpt-5-mini,gpt-5-nano,o3,o4-mini,gemini-2.5-pro/flash,gemini-2.0-flash.
xcstrings translate input.xcstrings -l fr -m haiku # fast/cheap
xcstrings translate input.xcstrings -l fr -m sonnet # balanced (default)
xcstrings translate input.xcstrings -l fr -m gpt-5.4-nano # cheapest
OpenRouter
Route through OpenRouter to reach any vendor with one key. Set
OPENROUTER_API_KEY, then pass an openrouter:vendor/model string or a shorthand alias:
| Alias | Model |
|---|---|
or-opus, or-sonnet, or-haiku |
Anthropic Claude (Opus 4.8 / Sonnet 4.6 / Haiku 4.5) |
or-gpt-5.5, or-gpt-5.4, or-gpt-5.4-mini, or-gpt-5.4-nano |
OpenAI GPT-5.5 / 5.4 family |
or-gpt-5, or-gpt-5-mini, or-gpt-5-nano |
OpenAI GPT-5 family |
or-gemini-3.5-flash, or-gemini-3.1-pro, or-gemini-3-flash |
Google Gemini 3.x |
or-gemini-pro, or-gemini-flash |
Google Gemini 2.5 Pro / Flash |
xcstrings translate input.xcstrings -l fr -m openrouter:anthropic/claude-sonnet-4.6
xcstrings translate input.xcstrings -l fr -m or-gpt-5.4-nano
Cost estimates for openrouter:* models are fetched live from OpenRouter's public
model catalog (cached ~24h under ~/.cache/xcstrings-translator/), so any model — even
brand-new ones — gets accurate pricing in estimate/--dry-run. Pass --no-fetch to
skip the network and use cached/static prices only.
Commands
| Command | Description |
|---|---|
translate |
Translate to specified languages |
estimate |
Preview cost without translating |
info |
Show file stats and coverage |
validate |
Check for issues |
languages |
List all 35+ supported languages |
Usage Examples
# Translate to multiple languages
xcstrings translate Localizable.xcstrings -l fr,es,it,de,ja
# Translate every .xcstrings under a project directory (recursive; asks first)
xcstrings translate ./MyApp -l fr,es,it
xcstrings translate ./MyApp --fill-missing -y # skip the confirmation prompt
# Estimate cost first
xcstrings translate Localizable.xcstrings -l fr,es,it --dry-run
# Use faster model
xcstrings translate Localizable.xcstrings -l fr -m haiku
# Parallel requests (faster for large files)
xcstrings translate Localizable.xcstrings -l fr,es -c 32
# Save to different file
xcstrings translate input.xcstrings -l fr -o translated.xcstrings
# Fill missing translations only
xcstrings translate Localizable.xcstrings --fill-missing
# Check translation coverage
xcstrings info Localizable.xcstrings
# Validate format specifiers
xcstrings validate Localizable.xcstrings
App Context
Provide context for better translations. Create context.md next to your xcstrings file:
# My Fitness App
A workout tracking app for athletes.
Tone: Motivational, energetic.
Use informal "you" (du/tu).
Or pass directly:
xcstrings translate input.xcstrings -l fr --context "A fitness app with motivational tone"
Python API
from xcstrings_translator import XCStringsFile, XCStringsTranslator
# Load
xcstrings = XCStringsFile.from_file("Localizable.xcstrings")
# Translate
translator = XCStringsTranslator(model="sonnet")
xcstrings = translator.translate_file(xcstrings, ["fr", "es", "it"])
# Save
xcstrings.to_file("Localizable.xcstrings")
# Stats
print(f"Translated: {translator.stats.translated}")
# Rates below are sonnet's ($3 in / $15 out per 1M tokens); adjust for your model.
print(f"Cost: ${translator.stats.input_tokens * 3 / 1e6 + translator.stats.output_tokens * 15 / 1e6:.2f}")
Supported Languages
European: en, de, fr, es, it, pt, pt-BR, pt-PT, nl, pl, sv, da, nb, fi, cs, sk, hu, ro, bg, el, sq, uk, ru, tr
Asian: ja, ko, zh-Hans, zh-Hant, th, vi, id, ms, hi
Middle Eastern: ar, he
Other: ca, eu
Options
| Option | Description | Default |
|---|---|---|
-l, --languages |
Target language codes | Required |
-m, --model |
AI model | sonnet |
-o, --output |
Output file | Overwrites input |
-b, --batch-size |
Strings per API call | 25 |
-c, --concurrency |
Parallel requests | 32 |
--context |
App description | context.md |
--overwrite |
Replace existing | false |
--dry-run |
Estimate only | false |
-f, --fill-missing |
Auto-detect languages | false |
-y, --yes |
Skip confirmation for directory runs | false |
Troubleshooting
"Unsupported language" - Use Apple codes: zh-Hans not zh-CN, pt-BR not pt_BR
Format mismatch - Run xcstrings validate to find issues
API errors - Check correct key is set for your model
Contributing
Contributions are welcome! See CONTRIBUTING.md for dev setup, tests, and the release process. Please also review our Code of Conduct. To report a security issue, see SECURITY.md.
License
MIT
Made with ❤️ by Justin Lanfermann
Metadata
Release files for xcstrings-translator 1.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| xcstrings_translator-1.1.3.tar.gz | 38.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| xcstrings_translator-1.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 63.1 kB
Release files / xcstrings_translator-1.1.3.tar.gz
| Download URL | xcstrings_translator-1.1.3.tar.gz |
|---|---|
| Size | 38.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
664d0077c431a71b80b3f990ec4a08a3f1fa2baa304c1e1364ad049886c1bc6a
|
|
BLAKE2b-256 checksum How to use checksums |
70d5f29d27fe19814de53db3902cc9166a74f8651d63b6b9e4673b861ee0f8a8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 7, 2026.
Transparency logRelease files / xcstrings_translator-1.1.3-py3-none-any.whl
| Download URL | xcstrings_translator-1.1.3-py3-none-any.whl |
|---|---|
| Size | 24.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
903311428723aa37b84d31d9282410d093ee5b8fdf26a28e8dae42f6c1e45e52
|
|
BLAKE2b-256 checksum How to use checksums |
0bb51396fb8f824ab35b6115e2839304058b3fbeabda674c36b264d8c63c8d1f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 7, 2026.
Transparency log