Translation management CLI for developers. Manage i18n translations, export to 6 formats (iOS, Android, Flutter, i18next), import translations, and collaborate with teams. Affordable alternative to Lokalise and Crowdin.
npm install langctl> CLI-first translation management for developers
Langctl is a powerful command-line tool that lets you manage translations directly from your terminal. Create projects, manage translation keys, invite team members, export in multiple formats, and integrate seamlessly into your CI/CD pipeline.
- 🚀 Complete Project Management - Create, update, and manage translation projects
- 🔑 Translation Key CRUD - Full control over translation keys and values
- 👥 Team Management - Invite members, manage roles, and handle invitations
- 📊 Organization Insights - View stats, plan limits, and usage metrics
- 📦 Multi-Format Export - Support for JSON, iOS, Android, Flutter, and i18n
- 🔄 Import Translations - Bulk import from JSON files
- 🤖 CI/CD Ready - Perfect for automated workflows
- 🌍 Multi-Language Support - Manage unlimited languages per project
``bash`
npm install -g langctl
Or use with npx (no installation required):
`bash`
npx langctl --help
1. Visit app.langctl.com and sign in
2. Go to Settings → API Keys
3. Click "Generate New Key"
4. Copy the key (it's only shown once!)
`bashInteractive setup
langctl init
$3
`bash
View organization info
langctl org infoCheck statistics
langctl org statsList your projects
langctl projects list
`$3
`bash
List translation keys
langctl keys list my-projectExport translations
langctl export my-project --language en --format jsonCreate a new key
langctl keys create my-project home.welcome \
--value-en "Welcome!" \
--value-es "¡Bienvenido!"
`---
Commands Overview
$3
- langctl init - Interactive setup wizard
- langctl auth - Authenticate with API key
- langctl logout - Clear credentials
- langctl config - View current configuration$3
- langctl org info - View organization details
- langctl org stats - View organization statistics
- langctl org plan - View subscription plan and limits$3
- langctl projects list - List all projects
- langctl projects create - Create new project
- langctl projects get - Get project details
- langctl projects update - Update project
- langctl projects delete - Delete project
- langctl projects add-language - Add language
- langctl projects remove-language - Remove language
- langctl projects stats - View project statistics$3
- langctl keys list - List translation keys
- langctl keys get - Get key details
- langctl keys create - Create new key
- langctl keys delete - Delete key
- langctl keys translate - Update translation
- langctl keys publish - Publish/unpublish keys$3
- langctl team list - List team members
- langctl team get - Get member details
- langctl team invite - Invite team member
- langctl team remove - Remove team member
- langctl team update-role - Update member role
- langctl team invitations - List invitations
- langctl team revoke-invitation - Revoke invitation$3
- langctl export - Export translations
- langctl import - Import translations---
Detailed Command Reference
$3
####
langctl initInteractive setup wizard that guides you through authentication and configuration.
`bash
langctl init
`####
langctl auth Authenticate with an API key from your dashboard.
`bash
langctl auth lc_abc123...
`####
langctl logoutClear stored authentication credentials.
`bash
langctl logout
`####
langctl configDisplay current configuration (API key, organization, etc.).
`bash
langctl config
`---
$3
####
langctl org infoView your organization details.
`bash
langctl org info
`Output:
- Organization name and ID
- Slug
- Subscription plan
- Creation date
####
langctl org statsView comprehensive organization statistics.
`bash
langctl org stats
`Output:
- Total team members
- Number of projects
- Translation key counts (total, published, unpublished)
- Languages used across projects
- API keys and webhooks
####
langctl org planView subscription plan details and resource limits.
`bash
langctl org plan
`Output:
- Current plan (Free, Pro, Team, Enterprise)
- Max members allowed
- Max projects allowed
- Max keys per project
- Max API keys allowed
---
$3
####
langctl projects listList all projects you have access to.
`bash
langctl projects list
`Output:
- Project name and slug
- Description
- Supported languages
- Default language
- Available modules
####
langctl projects create Create a new translation project.
`bash
langctl projects create "Mobile App" \
--description "iOS and Android translations" \
--languages en,es,fr,de \
--default-language en
`Options:
-
-d, --description - Project description
- -l, --languages - Comma-separated language codes (default: en)
- --default-language - Default language (default: first language)Examples:
`bash
Simple project with English only
langctl projects create "My App"Multi-language project
langctl projects create "Global App" \
-l en,es,fr,de,ja \
--default-language enWith description
langctl projects create "Mobile App" \
-d "Translation keys for mobile application" \
-l en,es
`####
langctl projects get Get detailed information about a specific project.
`bash
langctl projects get my-app
`Output:
- Project name, ID, and slug
- Description
- All supported languages
- Default language
- List of modules
####
langctl projects update Update project details.
`bash
langctl projects update my-app \
--name "New Name" \
--description "Updated description" \
--languages en,es,fr,de,ja \
--default-language en
`Options:
-
-n, --name - Update project name
- -d, --description - Update description
- -l, --languages - Update supported languages
- --default-language - Update default languageExamples:
`bash
Change project name
langctl projects update my-app --name "Better Name"Add more languages
langctl projects update my-app -l en,es,fr,de,ja,zhUpdate description only
langctl projects update my-app -d "New project description"
`####
langctl projects delete Delete a project (soft delete - can be recovered).
`bash
langctl projects delete my-app
`Warning: This will mark the project as deleted. Contact support to recover deleted projects.
####
langctl projects add-language Add a new language to an existing project.
`bash
langctl projects add-language my-app de
`Examples:
`bash
Add German
langctl projects add-language my-app deAdd Japanese
langctl projects add-language my-app jaAdd Chinese
langctl projects add-language my-app zh
`####
langctl projects remove-language Remove a language from a project.
`bash
langctl projects remove-language my-app de
`Note: Cannot remove the default language. Change default language first if needed.
####
langctl projects stats View project statistics.
`bash
langctl projects stats my-app
`Output:
- Total translation keys
- Published vs unpublished counts
- Number of modules
- List of module names
---
$3
####
langctl keys list List translation keys for a project.
`bash
langctl keys list my-app
`Options:
-
-m, --module - Filter by module
- -p, --published - Show only published keys
- -s, --search - Search in key names
- --limit - Limit results (default: 100)
- --offset - Offset for pagination (default: 0)Examples:
`bash
List all keys
langctl keys list my-appFilter by module
langctl keys list my-app --module authShow only published keys
langctl keys list my-app --publishedSearch for specific keys
langctl keys list my-app --search "welcome"Pagination
langctl keys list my-app --limit 50 --offset 0
langctl keys list my-app --limit 50 --offset 50
`####
langctl keys get Get detailed information about a specific translation key.
`bash
langctl keys get my-app home.welcome
`Output:
- Key name and ID
- Description
- Module
- Published status
- All translations for all languages
####
langctl keys create Create a new translation key with values for multiple languages.
`bash
langctl keys create my-app home.welcome \
--description "Welcome message on homepage" \
--module home \
--value-en "Welcome to our app!" \
--value-es "¡Bienvenido a nuestra aplicación!" \
--value-fr "Bienvenue dans notre application!" \
--value-de "Willkommen in unserer App!"
`Options:
-
-d, --description - Key description
- -m, --module - Module/namespace for organization
- --value-en - English translation
- --value-es - Spanish translation
- --value-fr - French translation
- --value-de - German translation
- --tags - Comma-separated tagsSupported language options:
You can use
--value-{language} for any language code in your project.Examples:
`bash
Simple key with one language
langctl keys create my-app button.submit --value-en "Submit"Multi-language key
langctl keys create my-app home.title \
--module home \
--value-en "Home" \
--value-es "Inicio" \
--value-fr "Accueil"With description and tags
langctl keys create my-app error.network \
--description "Network connection error" \
--module errors \
--value-en "Network error occurred" \
--tags error,network
`####
langctl keys delete Delete a translation key.
`bash
langctl keys delete my-app home.welcome
`####
langctl keys translate Update the translation value for a specific language.
`bash
langctl keys translate my-app home.welcome \
--language es \
--value "¡Bienvenido!"
`Options:
-
-l, --language - Language code (required)
- -v, --value - Translation value (required)Examples:
`bash
Update Spanish translation
langctl keys translate my-app home.title -l es -v "Inicio"Update French translation
langctl keys translate my-app button.submit -l fr -v "Soumettre"Add translation for new language
langctl keys translate my-app home.welcome -l de -v "Willkommen"
`####
langctl keys publish Publish or unpublish translation keys.
`bash
Publish keys
langctl keys publish my-app home.welcome home.title button.submitUnpublish keys
langctl keys publish my-app home.welcome --unpublish
`Options:
-
--unpublish - Unpublish instead of publishExamples:
`bash
Publish single key
langctl keys publish my-app home.welcomePublish multiple keys
langctl keys publish my-app home.welcome home.title home.subtitleUnpublish keys
langctl keys publish my-app test.key --unpublish
`---
$3
####
langctl team listList all team members in your organization.
`bash
langctl team list
`Output:
- Member email
- Role (viewer, member, admin, owner)
- Join date
####
langctl team get Get details about a specific team member.
`bash
langctl team get user@example.com
`####
langctl team invite Invite a new team member.
`bash
langctl team invite user@example.com --role member
`Options:
-
-r, --role - Member role (default: member)
- viewer - Read-only access
- member - Can manage translations
- admin - Full project and team managementExamples:
`bash
Invite as member (default)
langctl team invite user@example.comInvite as admin
langctl team invite admin@example.com --role adminInvite as viewer
langctl team invite viewer@example.com --role viewer
`####
langctl team remove Remove a team member from your organization.
`bash
langctl team remove user@example.com
`Note: Cannot remove the organization owner. Cannot remove yourself (use appropriate UI for that).
####
langctl team update-role Update a team member's role.
`bash
langctl team update-role user@example.com admin
`Valid roles:
viewer, member, adminExamples:
`bash
Promote to admin
langctl team update-role user@example.com adminDemote to viewer
langctl team update-role user@example.com viewer
`####
langctl team invitationsList all invitations (pending, accepted, or cancelled).
`bash
List all invitations
langctl team invitationsList only pending invitations
langctl team invitations --pending
`Options:
-
-p, --pending - Show only pending invitations####
langctl team revoke-invitation Revoke a pending invitation.
`bash
langctl team revoke-invitation user@example.com
`---
$3
####
langctl export Export translations in various formats.
`bash
langctl export my-app --language en --format flat-json
`Options:
-
-l, --language - Language to export (default: exports all languages)
- -f, --format - Export format (default: flat-json)
- -o, --output - Output file path (optional)
- -m, --module - Export only specific module
- --include-unpublished - Include unpublished keys (default: published only)Supported formats:
-
flat-json - Flat key-value JSON (default)
- nested-json - Nested JSON structure
- i18n-json - i18next compatible format
- android-xml - Android strings.xml format
- ios-strings - iOS Localizable.strings format
- flutter-arb - Flutter ARB formatExamples:
`bash
Export single language as JSON
langctl export my-app -l en -f flat-jsonExport all languages
langctl export my-appExport for iOS
langctl export my-app -l en -f ios-strings -o ./ios/en.lproj/Localizable.stringsExport for Android
langctl export my-app -l es -f android-xml -o ./android/res/values-es/strings.xmlExport for Flutter
langctl export my-app -l fr -f flutter-arb -o ./lib/l10n/app_fr.arbExport specific module
langctl export my-app -l en --module authInclude unpublished translations
langctl export my-app -l en --include-unpublished
`####
langctl import Import translations from a JSON file.
`bash
langctl import my-app translations.json --language en
`Options:
-
-l, --language - Target language (required)
- --overwrite - Overwrite existing translations
- --publish - Auto-publish imported keysExamples:
`bash
Import English translations
langctl import my-app en.json -l enImport and overwrite existing
langctl import my-app en.json -l en --overwriteImport and auto-publish
langctl import my-app en.json -l en --publishImport multiple languages
langctl import my-app en.json -l en --publish
langctl import my-app es.json -l es --publish
langctl import my-app fr.json -l fr --publish
`Supported JSON formats:
`json
// Flat format (recommended)
{
"home.welcome": "Welcome!",
"home.subtitle": "Get started",
"button.submit": "Submit"
}// Nested format (auto-flattened)
{
"home": {
"welcome": "Welcome!",
"subtitle": "Get started"
},
"button": {
"submit": "Submit"
}
}
`---
Export Format Examples
$3
`json
{
"home.welcome": "Welcome!",
"home.subtitle": "Get started with {{appName}}",
"button.submit": "Submit"
}
`$3
`json
{
"home": {
"welcome": "Welcome!",
"subtitle": "Get started with {{appName}}"
},
"button": {
"submit": "Submit"
}
}
`$3
`json
{
"home": {
"welcome": "Welcome!",
"subtitle": "Get started with {{appName}}"
}
}
`$3
`
/ Welcome message /
"home.welcome" = "Welcome!";/ Homepage subtitle with app name placeholder /
"home.subtitle" = "Get started with %@";
`$3
`xml
Welcome!
Get started with %1$s
`$3
`json
{
"@@locale": "en",
"home.welcome": "Welcome!",
"@home.welcome": {
"description": "Welcome message"
},
"home.subtitle": "Get started with {appName}",
"@home.subtitle": {
"description": "Homepage subtitle",
"placeholders": {
"appName": {
"type": "String"
}
}
}
}
`---
Real-World Workflows
$3
`bash
1. Authenticate
langctl auth lc_your_api_key_here2. Create project
langctl projects create "Mobile App" \
-l en,es,fr,de \
--default-language en \
-d "iOS and Android application"3. Add translation keys
langctl keys create mobile-app home.welcome \
--module home \
--value-en "Welcome!" \
--value-es "¡Bienvenido!" \
--value-fr "Bienvenue!"langctl keys create mobile-app button.submit \
--module common \
--value-en "Submit" \
--value-es "Enviar" \
--value-fr "Soumettre"
4. Publish keys
langctl keys publish mobile-app home.welcome button.submit5. Export for platforms
langctl export mobile-app -l en -f ios-strings -o ./ios/en.lproj/
langctl export mobile-app -l en -f android-xml -o ./android/res/values/
`$3
`bash
1. Prepare JSON files (en.json, es.json, fr.json)
2. Import all languages
langctl import my-app en.json -l en --publish
langctl import my-app es.json -l es --publish
langctl import my-app fr.json -l fr --publish3. Verify imports
langctl keys list my-app --published
langctl projects stats my-app
`$3
`bash
1. Invite team members
langctl team invite developer@example.com --role member
langctl team invite manager@example.com --role admin2. Check invitations
langctl team invitations --pending3. Manage roles
langctl team update-role developer@example.com admin4. View team
langctl team list
`$3
`bash
Export for all platforms
PROJECT="my-app"
LANG="en"Web (i18next)
langctl export $PROJECT -l $LANG -f i18n-json -o ./src/locales/$LANG.jsoniOS
langctl export $PROJECT -l $LANG -f ios-strings -o ./ios/$LANG.lproj/Localizable.stringsAndroid
langctl export $PROJECT -l $LANG -f android-xml -o ./android/res/values/strings.xmlFlutter
langctl export $PROJECT -l $LANG -f flutter-arb -o ./lib/l10n/app_$LANG.arb
`---
CI/CD Integration
$3
Automated translation sync workflow:
`yaml
name: Sync Translationson:
schedule:
- cron: '0 0 *' # Daily at midnight
workflow_dispatch: # Manual trigger
jobs:
sync-translations:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install Langctl
run: npm install -g langctl
- name: Authenticate
env:
LANGCTL_API_KEY: ${{ secrets.LANGCTL_API_KEY }}
run: langctl auth $LANGCTL_API_KEY
- name: Export Translations
run: |
langctl export my-project -l en -f i18n-json -o ./locales/en.json
langctl export my-project -l es -f i18n-json -o ./locales/es.json
langctl export my-project -l fr -f i18n-json -o ./locales/fr.json
- name: Commit Changes
run: |
git config user.name "Langctl Bot"
git config user.email "bot@langctl.com"
git add locales/
git diff --staged --quiet || git commit -m "chore: update translations [skip ci]"
git push
`$3
`yaml
sync-translations:
image: node:18
script:
- npm install -g langctl
- langctl auth $LANGCTL_API_KEY
- langctl export my-project -l en -f json -o ./locales/en.json
- langctl export my-project -l es -f json -o ./locales/es.json
- git config user.name "Langctl Bot"
- git config user.email "bot@langctl.com"
- git add locales/
- git diff --staged --quiet || git commit -m "chore: update translations"
- git push origin $CI_COMMIT_BRANCH
only:
- schedules
`$3
`dockerfile
FROM node:18-alpineRUN npm install -g langctl
WORKDIR /app
COPY . .
Set API key via environment variable
ENV LANGCTL_API_KEY=""Example: Export translations on build
RUN langctl auth $LANGCTL_API_KEY && \
langctl export my-project -l en -f json -o ./public/locales/en.json
`---
Best Practices
$3
1. Use modules to organize keys by feature:
`bash
langctl keys create app auth.login.title --module auth
langctl keys create app home.hero.title --module home
langctl keys create app settings.profile.name --module settings
`2. Follow naming conventions:
`
module.screen.element
auth.login.title
home.hero.subtitle
`3. Add descriptions to keys:
`bash
langctl keys create app button.submit \
--description "Primary action button across the app" \
--value-en "Submit"
`$3
1. Create keys unpublished (draft mode)
2. Add translations for all languages
3. Review and test translations
4. Publish when ready:
`bash
langctl keys publish my-app key1 key2 key3
`5. Export published translations only:
`bash
langctl export my-app -l en
`$3
1. Use appropriate roles:
-
viewer - Stakeholders, reviewers (read-only)
- member - Translators, content writers
- admin - Project managers, team leads2. Regular access reviews:
`bash
langctl team list
langctl team invitations
`$3
1. Never commit API keys to version control
2. Use environment variables:
`bash
export LANGCTL_API_KEY="lc_..."
langctl auth $LANGCTL_API_KEY
`3. Rotate keys periodically from app.langctl.com
4. Use different keys for different environments:
- Development key for local work
- CI/CD key for automated workflows
- Production key for releases
---
Troubleshooting
$3
"Not authenticated" error:
`bash
Solution: Authenticate with your API key
langctl auth lc_your_api_key_here
`"Invalid API key" error:
- Verify key format (starts with
lc_, 67 characters total)
- Check key hasn't been revoked at app.langctl.com
- Generate a new key if needed$3
"Project not found" error:
`bash
Check project slug (not name)
langctl projects listUse the slug shown in the list
langctl keys list correct-slug-here
`Cannot remove language:
- Cannot remove the default language
- Change default language first:
`bash
langctl projects update my-app --default-language en
langctl projects remove-language my-app fr
`$3
Import fails with format error:
- Ensure JSON is valid
- Use flat key-value format or nested objects
- Check language code is valid
Export shows no keys:
- Verify keys are published:
`bash
langctl keys list my-app --published
`
- Or include unpublished:
`bash
langctl export my-app -l en --include-unpublished
`$3
If experiencing connectivity problems:
1. Check your internet connection
2. Verify you're not behind a restrictive firewall
3. Try again in a few moments
4. Contact support if issue persists
---
FAQ
Q: What's the difference between slug and name?
A: The slug is the URL-friendly identifier (e.g.,
my-app), while the name is the display name (e.g., "My App"). Use slugs in CLI commands.Q: Can I use the CLI without installing it?
A: Yes! Use
npx langctl instead of langctl for any command.Q: How do I get my project slug?
A: Run
langctl projects list to see all project slugs.Q: Can I export multiple languages at once?
A: Yes, run
langctl export my-app without -l flag to export all languages.Q: What happens to unpublished keys?
A: They're excluded from exports by default. Use
--include-unpublished to include them.Q: Can I undo a delete operation?
A: Projects and keys use soft deletes. Contact support to recover deleted items.
Q: How do I change my default language?
A: Run:
langctl projects update my-app --default-language `Q: Can I use the CLI in CI/CD?
A: Yes! Store your API key as a secret and use it in your workflow. See CI/CD Integration.
---
Platform Support
- ✅ macOS (Apple Silicon & Intel)
- ✅ Linux (x64, ARM64)
- ✅ Windows (x64, ARM64)
- ✅ Node.js 16.0.0 or higher
---
Links
- Website: langctl.com
- Dashboard: app.langctl.com
- Documentation: langctl.com/docs
- GitHub: github.com/siddharthsaxena0/langctl
- Report Issues: github.com/siddharthsaxena0/langctl/issues
- Email Support: hello@langctl.com
---
Contributing
We welcome contributions! Please see our contributing guidelines for details.
---
License
MIT License - see LICENSE file for details.
---
Built with ❤️ by the Langctl team
Making translation management simple, fast, and developer-friendly.