CLI tool to cherry-pick localization keys from Lokalise and merge them into existing .strings and .stringsdict files without overwriting unrelated keys. Useful in multi-developer projects with parallel feature branches, where full file downloads aren't an option.
- macOS (for Keychain-based token storage; non-macOS users can fall back to
api_token_env) - Python 3
- jq
- yq
brew install jq yq
git clone git@github.com:pkrll/lokalise-sync.git
cd lokalise-sync
chmod +x lokalise-sync.sh
ln -s "$(pwd)/lokalise-sync.sh" /usr/local/bin/lokalise-sync- Add a
.lokalise-sync.ymlconfig file to your project root. The recommended token source is the macOS Keychain — no secrets in git, no shell env to keep in sync:
lokalise:
project_id: "YOUR_PROJECT_ID"
# Recommended: read the token from the macOS Keychain.
# `keychain_service` is any string you choose — use one per project so tokens
# don't collide. `keychain_account` is usually just "api-token".
keychain_service: "lokalise-<your-project>"
keychain_account: "api-token"
# Alternatives (lower precedence, kept for portability / CI):
# api_token_env: "LOKALISE_API_TOKEN" # read from env var
# api_token: "your-actual-token-here" # hardcode (DISCOURAGED — leaks via git)
languages:
- iso: "en"
lproj: "en.lproj"
- iso: "sv"
lproj: "sv.lproj"
# where .lproj dirs live
base_path: "path/to/Resources"
files:
- lokalise_filename: "Localizable.strings"
local_filename: "Localizable.strings"
format: "strings"
- lokalise_filename: "Localizable.stringsdict"
local_filename: "Localizable.stringsdict"
format: "stringsdict"- Run the interactive setup from the project root:
lokalise-sync setupIt checks that all required tools are installed, reads the keychain_service /
keychain_account from your config, and prompts for the token (input is hidden).
Re-running setup is safe — it short-circuits when a token is already stored.
Token resolution precedence at runtime:
api_token → api_token_env → Keychain (keychain_service + keychain_account)
- Run
lokalise-syncfrom the project root.
# Sync specific keys
lokalise-sync "login.title" "login.subtitle"
# Sync by tag
lokalise-sync --tag "sprint-42"
# Wildcard — sync all keys matching a prefix
lokalise-sync "login.*"
# Mix exact keys and wildcards
lokalise-sync "login.title" "error.*"
# Preview without modifying files
lokalise-sync --dry-run "some.key"
# Limit to specific languages
lokalise-sync --langs sv,en "some.key"
# Full sync
lokalise-syncRun lokalise-sync --help for all options.
lokalise-sync.sh # CLI entry point — API calls, config, orchestration
.lokalise-sync.yml # Config, lives in your project root (per-project)
lib/
merge_strings.py # .strings parsing, filtering, alphabetical merge
merge_stringsdict.py # .stringsdict plist merge via plistlib