Portkey is a Swift command-line tool that helps you move localized string entries between modules or bundles in your iOS project.
While the name Portkey is a lighthearted nod to magical teleportation, this project is in no way affiliated with or endorsing the views of any TERF, including that one. Trans rights are human rights 🏳️⚧️
In modular iOS projects, each module often maintains its own localization files. But as code moves between modules, or into or out of the main bundle, localized strings can get left behind leading to broken UIs or missing translations.
Portkey solves this by:
- Finding a localization key in the source module
- Removing it from the source localization file(s)
- Moving it (with any associated comments) to the respective destination file(s)
It's like mv
, but for localized string key/values. 💫
To use this tool, download the binary from Github here. Then, run the binary from the command line to move strings between localization bundles:
portkey --key=<key> --from=<sourcePath> --to=<destinationPath>
portkey --key="HomePage.title" --from=./Modules/Login/Localization --to=./Modules/Onboarding/Localization
This moves the HomePage.title
key from each locale’s .strings
file in the Login module to the corresponding file in the Onboarding module.
You can also use the tool to rename a key within a module (or rename it upon moving):
portkey --key="HomePage.title" --new-key="HomePage.Title.new" --from=./Modules/Login/Localization
In this case, we only pass a source path, but we provide the optional new key argument, so it removes the original key, and adds it to the same file with a new key name.
To move multiple keys, use the keys
argument to provide a comma-separated list of keys:
portkey --keys=HomePage.title,HomePage.subtitle,HomePage.footer --from=./Modules/Login/Localization --to=./Modules/Onboarding/Localization
- ✅ .strings files
- ✅ Per-locale *.lproj directories (e.g., en.lproj/Localizable.strings)
- ✅ Moving comments (/_ comment _/, // comment) associated with the key
- ✅ Optional renaming of keys when moving
- ✅ Graceful skipping if key not found or destination file doesn’t exist
- ✅ Graceful skipping if key collision at destination
For each locale found in the source module:
- Portkey looks for supported file types (currently just
.strings
) - If the source file exists and contains the key:
- Portkey removes the entry and any comment above it
- If a matching destination file exists, Portkey appends the entry to it
- The key is moved once per locale.
- 💨 Move multiple strings at once
- ⏳ Support for .stringsdict files
- 📣 --verbose or --quiet flags
To build the script locally, clone the project and execute the following in the command line at the source root:
swift build
To run the script locally:
swift run portkey --key=<key> --from=<sourcePath> --to=<destinationPath>
To package a new release executable, run:
swift build -c release
This will output a new executable binary at .build/release/portkey
.