langctl is a command-line tool for managing translations. It’s designed for developers who want localization to feel like a natural part of their development workflow, not a separate process requiring different tools and interfaces.
This guide explains why langctl exists, how it approaches translation management, and gives you a high-level view of the workflow. For detailed commands and options, see the official documentation.
Why langctl Exists
Most translation management tools were built for a world where developers and translators work in separate systems. Developers export files, upload them somewhere, translators work in a web interface, and developers eventually import the results.
This workflow makes sense for large organizations with dedicated localization teams. But for many teams—especially small startups, indie developers, and technical products—it creates unnecessary friction:
- Constant context switching between terminal and browser
- Translation files that don’t integrate cleanly with Git
- Expensive per-seat pricing for features you don’t need
- Complex setup for simple requirements
langctl takes a different approach. The command line is the primary interface. Translation files live in your repository, and Git holds their history.
Core Principles
CLI-first, not CLI-only
The terminal is where developers work. langctl makes common operations available as simple commands:
langctl init # Set up the repo (writes langctl.json)
langctl push # Upload new strings from your source-language file
langctl pull # Download translations into your locale files
langctl projects stats web-app # Translation coverage per language
This doesn’t mean web interfaces are bad. langctl includes a web app for situations where visual interfaces help—reviewing translations, managing API keys. But the day-to-day workflow doesn’t require opening a browser.
Git as source of truth
Translation files are code artifacts. They should be versioned, reviewed in pull requests, and maintained with the same rigor as any other source file.
langctl keeps the translation files your app ships committed in your repository. langctl pull writes them deterministically—sorted, no timestamps—so a pull only changes a file when a translation actually changed. This means:
- Full history of translation changes in Git
- Changes appear in diffs and code review
- Branching strategies apply to translations
- CI can verify committed files are current with
langctl pull --check
Simple by default, powerful when needed
Most translation work is straightforward: add keys, translate them, ship. langctl makes the common case fast and adds capabilities when you actually need them.
You don’t need to configure modules, language filters, or review steps to get started. A project, a file format, and an output path are enough; everything else is optional.
The Workflow
Here’s how langctl fits into typical development:
Initial setup
Install and initialize once per project:
# Install globally
npm install -g langctl
# Initialize in your project
cd your-project
langctl init
# Follow prompts: API key, project, file format and location
This writes a langctl.json you can commit, so langctl pull and langctl push need no arguments. Node.js 20 or newer is required.
Daily development
As you build features, you add translation keys to your code using your framework’s i18n library (react-i18next, vue-i18n, @angular/localize, etc.).
// In your code
const message = t('welcome.greeting');
Add the new key and its text to your source-language file (for example src/locales/en.json), then upload it:
langctl push
push uploads new keys from your source-language file. It doesn’t scan your code—the source file is the list of keys.
Adding translations
Or create a key with its translations in one command:
langctl keys create web-app welcome.greeting --value en="Hello!" --value es="¡Hola!" --publish
New keys are drafts until they’re published (--publish here, or langctl keys publish web-app --all later); pull only includes published keys.
Team collaboration
Sync changes with your team:
# Pull changes others have made
langctl pull
# Push your changes
langctl push
This keeps everyone’s local files in sync with the shared state. By default push only adds new keys; it won’t overwrite existing translations unless you pass --overwrite.
Before deploying
Check translation status:
langctl pull --require-complete
This fails (exit code 1) if any language is missing translations. langctl projects stats web-app shows coverage per language, and in CI langctl pull --check fails (exit code 7) when committed files are out of date.
What You Get
Using langctl provides:
Speed: Adding a key is a single command, not a browser workflow.
Integration: Translations participate in your normal Git workflow—commits, diffs, pull requests.
Simplicity: Start with just files and commands. Add features as you need them.
Affordability: Pricing designed for small teams, not enterprise localization budgets.
Control: Your data lives in your repository in standard formats. You’re not locked in.
What langctl Isn’t
langctl is intentionally focused. It’s not:
- A translation memory system: No reuse of previous translations across keys
- A translator collaboration platform: Non-technical translators may prefer visual interfaces
- An enterprise solution: Large teams with complex workflows may need more sophisticated platforms
If you need those things, tools like Lokalise or Phrase may be better fits. langctl is for teams where developers handle translations and want that work to feel native to their workflow.
Getting Started
Ready to try it?
# Install
npm install -g langctl
# In your project
langctl init
langctl init asks for an API key (create one at app.langctl.com), lets you pick the project, file format and location, and writes langctl.json. Then run langctl pull and you have translation files in your repo.
For detailed documentation, configuration options, and advanced features, visit the langctl documentation.
Related reading: CLI-Based i18n Management explores the philosophy behind CLI-first localization in more depth.