A CLI tool that translates Xcode Localizable.strings files using Google Gemini AI.
Run it from your iOS/macOS project directory, point it at a source language, and it writes properly formatted target .lproj files — preserving keys, comments, format specifiers, and structure.
- Interactive setup — verifies your Gemini API key, lists available text models, and saves project settings locally
- Single-language translation — e.g.
en.lproj→tr.lproj - Bulk translation — translate one source language into many targets in one run (
tr,de,es,zh-Hans,...) - Incremental updates — skips strings that are already translated; only new or changed source strings are sent to the API
- Custom prompt — edit the translation prompt to match your app's tone and terminology
- Smart file discovery — finds
Localizable.stringsrecursively under your project root - Safe by default — automatically adds
.envand.xcode-translator/to your.gitignoreso API keys are not committed
- Node.js 18+
- A Google Gemini API key with billing enabled
Clone and build the CLI:
git clone https://github.com/Webisso/xcode-translator.git
cd xcode-translator
npm install
npm run buildLink it locally so you can run it with npx:
npm linkOr run it directly from the repo path:
npx /path/to/xcode-translator- Go to your Xcode project directory (where your
.lprojfolders live):
cd /path/to/your/ios-app- Run setup (first time only):
npx xcode-translator setupYou'll be asked for:
- Gemini API key (validated live against Google's API)
- Gemini model (e.g.
gemini-2.0-flash) - Source language (e.g.
en) - Target language (e.g.
tr)
- Translate:
npx xcode-translatorThat's it. The tool finds en.lproj/Localizable.strings, translates it, and writes tr.lproj/Localizable.strings.
| Command | Description |
|---|---|
npx xcode-translator |
Translate using saved source → target languages |
npx xcode-translator setup |
Configure API key, model, and languages |
npx xcode-translator bulk |
Translate to multiple target languages |
npx xcode-translator status |
Show current configuration |
npx xcode-translator prompt edit |
Open the translation prompt in your editor |
npx xcode-translator prompt show |
Print the current prompt |
npx xcode-translator prompt reset |
Reset prompt to default |
npx xcode-translator prompt path |
Print prompt file path |
Translate
npx xcode-translator --force # Re-translate all strings
npx xcode-translator -c /path/to/app # Use a specific project directoryBulk translate
npx xcode-translator bulk --from en --to tr,de,es,ja,zh-Hans,zh-Hant
npx xcode-translator bulk --force # Re-translate all strings for every languageWhen you run setup, the following files are created in your Xcode project directory (not inside the CLI repo):
| Path | Purpose |
|---|---|
.env |
API key, model, source/target languages |
.xcode-translator/translation-prompt.txt |
Editable translation prompt |
.xcode-translator/translation-state.json |
Tracks which source strings were already translated |
Example .env:
GEMINI_API_KEY=your_key_here
GEMINI_MODEL=gemini-2.0-flash
SOURCE_LANG=en
TARGET_LANG=tr
PROJECT_ROOT=/path/to/your/ios-appSetup automatically protects sensitive files from being committed to git:
-
If a
.gitignoreexists in your project directory or any parent directory up to the git repo root, the tool appends:# xcode-translator (auto-added — keeps API keys local) .env .xcode-translator/ -
If you're inside a git repository but no
.gitignoreexists on that path, one is created in your project directory.
Never commit your .env file. If you accidentally exposed an API key, revoke it in Google AI Studio and create a new one.
On subsequent runs, the tool:
- Reads the existing target
Localizable.strings - Skips keys that are already translated and unchanged
- Translates only new keys or keys whose source text changed
- Reports how many strings were translated vs skipped
Use --force to re-translate everything from scratch.
Any Xcode .lproj folder name is supported, including:
en,tr,de,ja,kopt-BR,zh-Hans,zh-Hant,es-419
Bulk example:
npx xcode-translator bulk --from en --to tr,de,es,ja,fr,ko,pt-BR,zh-Hans,zh-HantThe default prompt instructs Gemini to:
- Preserve
%@,%d,%1$@, and other format specifiers - Keep escape sequences (
\n,\", etc.) - Use concise, UI-appropriate phrasing
- Return a JSON array of translated strings
Edit it anytime:
npx xcode-translator prompt editPlaceholders in the prompt:
| Placeholder | Replaced with |
|---|---|
{{SOURCE_LANG}} |
Source language code |
{{TARGET_LANG}} |
Target language code |
{{STRINGS_JSON}} |
JSON array of strings to translate |
API key rejected (403)
If Google returns an error like Lightning dunning decision is deny, your API key format may be valid but the linked Google Cloud project has a billing or payment issue. Fix billing at Google Cloud Console and try again.
No strings to translate
All keys are already translated and unchanged. Add new keys to your source Localizable.strings or run with --force.
Source file not found
Make sure you run the CLI from your Xcode project root (or pass -c). The tool searches recursively for {lang}.lproj/Localizable.strings.
This project is licensed under the MIT License.