CLI-first translation management for developers
π Website β’ π Documentation β’ π Get Started β’ π¬ Support
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.
π New to Langctl? Visit langctl.com to learn more about features, pricing, and see how Langctl compares to other translation tools.
- π 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
npm install -g langctlOr use with npx (no installation required):
npx langctl --helpπ First time here? Check out our Getting Started Guide on the website for a complete walkthrough!
- Visit app.langctl.com and create a free account
- Go to Settings β API Keys
- Click "Generate New Key"
- Copy the key (it's only shown once!)
π‘ Tip: Learn more about API keys and authentication at langctl.com/docs/cli/authentication
# Interactive setup
langctl init
# Or authenticate directly
langctl auth lc_your_api_key_here# View organization info
langctl org info
# Check statistics
langctl org stats
# List your projects
langctl projects list# List translation keys
langctl keys list my-project
# Export translations
langctl export my-project --language en --format json
# Create a new key
langctl keys create my-project home.welcome \
--value-en "Welcome!" \
--value-es "Β‘Bienvenido!"langctl init- Interactive setup wizardlangctl auth <api-key>- Authenticate with API keylangctl logout- Clear credentialslangctl config- View current configuration
langctl org info- View organization detailslangctl org stats- View organization statisticslangctl org plan- View subscription plan and limits
langctl projects list- List all projectslangctl projects create <name>- Create new projectlangctl projects get <slug>- Get project detailslangctl projects update <slug>- Update projectlangctl projects delete <slug>- Delete projectlangctl projects add-language <slug> <language>- Add languagelangctl projects remove-language <slug> <language>- Remove languagelangctl projects stats <slug>- View project statistics
langctl keys list <project>- List translation keyslangctl keys get <project> <key>- Get key detailslangctl keys create <project> <key>- Create new keylangctl keys delete <project> <key>- Delete keylangctl keys translate <project> <key>- Update translationlangctl keys publish <project> <keys...>- Publish/unpublish keys
langctl team list- List team memberslangctl team get <email>- Get member detailslangctl team invite <email>- Invite team memberlangctl team remove <email>- Remove team memberlangctl team update-role <email> <role>- Update member rolelangctl team invitations- List invitationslangctl team revoke-invitation <email>- Revoke invitation
langctl export <project>- Export translationslangctl import <project> <file>- Import translations
Interactive setup wizard that guides you through authentication and configuration.
langctl initAuthenticate with an API key from your dashboard.
langctl auth lc_abc123...Clear stored authentication credentials.
langctl logoutDisplay current configuration (API key, organization, etc.).
langctl configView your organization details.
langctl org infoOutput:
- Organization name and ID
- Slug
- Subscription plan
- Creation date
View comprehensive organization statistics.
langctl org statsOutput:
- Total team members
- Number of projects
- Translation key counts (total, published, unpublished)
- Languages used across projects
- API keys and webhooks
View subscription plan details and resource limits.
langctl org planOutput:
- Current plan (Free, Pro, Team, Enterprise)
- Max members allowed
- Max projects allowed
- Max keys per project
- Max API keys allowed
List all projects you have access to.
langctl projects listOutput:
- Project name and slug
- Description
- Supported languages
- Default language
- Available modules
Create a new translation project.
langctl projects create "Mobile App" \
--description "iOS and Android translations" \
--languages en,es,fr,de \
--default-language enOptions:
-d, --description <text>- Project description-l, --languages <langs>- Comma-separated language codes (default:en)--default-language <code>- Default language (default: first language)
Examples:
# 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 en
# With description
langctl projects create "Mobile App" \
-d "Translation keys for mobile application" \
-l en,esGet detailed information about a specific project.
langctl projects get my-appOutput:
- Project name, ID, and slug
- Description
- All supported languages
- Default language
- List of modules
Update project details.
langctl projects update my-app \
--name "New Name" \
--description "Updated description" \
--languages en,es,fr,de,ja \
--default-language enOptions:
-n, --name <name>- Update project name-d, --description <text>- Update description-l, --languages <langs>- Update supported languages--default-language <code>- Update default language
Examples:
# 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,zh
# Update description only
langctl projects update my-app -d "New project description"Delete a project (soft delete - can be recovered).
langctl projects delete my-appWarning: This will mark the project as deleted. Contact support to recover deleted projects.
Add a new language to an existing project.
langctl projects add-language my-app deExamples:
# Add German
langctl projects add-language my-app de
# Add Japanese
langctl projects add-language my-app ja
# Add Chinese
langctl projects add-language my-app zhRemove a language from a project.
langctl projects remove-language my-app deNote: Cannot remove the default language. Change default language first if needed.
View project statistics.
langctl projects stats my-appOutput:
- Total translation keys
- Published vs unpublished counts
- Number of modules
- List of module names
List translation keys for a project.
langctl keys list my-appOptions:
-m, --module <name>- Filter by module-p, --published- Show only published keys-s, --search <term>- Search in key names--limit <number>- Limit results (default: 100)--offset <number>- Offset for pagination (default: 0)
Examples:
# List all keys
langctl keys list my-app
# Filter by module
langctl keys list my-app --module auth
# Show only published keys
langctl keys list my-app --published
# Search 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 50Get detailed information about a specific translation key.
langctl keys get my-app home.welcomeOutput:
- Key name and ID
- Description
- Module
- Published status
- All translations for all languages
Create a new translation key with values for multiple languages.
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 <text>- Key description-m, --module <name>- Module/namespace for organization--value-en <value>- English translation--value-es <value>- Spanish translation--value-fr <value>- French translation--value-de <value>- German translation--tags <tags>- Comma-separated tags
Supported language options:
You can use --value-{language} for any language code in your project.
Examples:
# 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,networkDelete a translation key.
langctl keys delete my-app home.welcomeUpdate the translation value for a specific language.
langctl keys translate my-app home.welcome \
--language es \
--value "Β‘Bienvenido!"Options:
-l, --language <code>- Language code (required)-v, --value <text>- Translation value (required)
Examples:
# 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"Publish or unpublish translation keys.
# Publish keys
langctl keys publish my-app home.welcome home.title button.submit
# Unpublish keys
langctl keys publish my-app home.welcome --unpublishOptions:
--unpublish- Unpublish instead of publish
Examples:
# Publish single key
langctl keys publish my-app home.welcome
# Publish multiple keys
langctl keys publish my-app home.welcome home.title home.subtitle
# Unpublish keys
langctl keys publish my-app test.key --unpublishList all team members in your organization.
langctl team listOutput:
- Member email
- Role (viewer, member, admin, owner)
- Join date
Get details about a specific team member.
langctl team get user@example.comInvite a new team member.
langctl team invite user@example.com --role memberOptions:
-r, --role <role>- Member role (default:member)viewer- Read-only accessmember- Can manage translationsadmin- Full project and team management
Examples:
# Invite as member (default)
langctl team invite user@example.com
# Invite as admin
langctl team invite admin@example.com --role admin
# Invite as viewer
langctl team invite viewer@example.com --role viewerRemove a team member from your organization.
langctl team remove user@example.comNote: Cannot remove the organization owner. Cannot remove yourself (use appropriate UI for that).
Update a team member's role.
langctl team update-role user@example.com adminValid roles: viewer, member, admin
Examples:
# Promote to admin
langctl team update-role user@example.com admin
# Demote to viewer
langctl team update-role user@example.com viewerList all invitations (pending, accepted, or cancelled).
# List all invitations
langctl team invitations
# List only pending invitations
langctl team invitations --pendingOptions:
-p, --pending- Show only pending invitations
Revoke a pending invitation.
langctl team revoke-invitation user@example.comExport translations in various formats.
langctl export my-app --language en --format flat-jsonOptions:
-l, --language <code>- Language to export (default: exports all languages)-f, --format <type>- Export format (default:flat-json)-o, --output <path>- Output file path (optional)-m, --module <name>- 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 structurei18n-json- i18next compatible formatandroid-xml- Android strings.xml formatios-strings- iOS Localizable.strings formatflutter-arb- Flutter ARB format
Examples:
# Export single language as JSON
langctl export my-app -l en -f flat-json
# Export all languages
langctl export my-app
# Export for iOS
langctl export my-app -l en -f ios-strings -o ./ios/en.lproj/Localizable.strings
# Export for Android
langctl export my-app -l es -f android-xml -o ./android/res/values-es/strings.xml
# Export for Flutter
langctl export my-app -l fr -f flutter-arb -o ./lib/l10n/app_fr.arb
# Export specific module
langctl export my-app -l en --module auth
# Include unpublished translations
langctl export my-app -l en --include-unpublishedImport translations from a JSON file.
langctl import my-app translations.json --language enOptions:
-l, --language <code>- Target language (required)--overwrite- Overwrite existing translations--publish- Auto-publish imported keys
Examples:
# Import English translations
langctl import my-app en.json -l en
# Import and overwrite existing
langctl import my-app en.json -l en --overwrite
# Import and auto-publish
langctl import my-app en.json -l en --publish
# Import 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 --publishSupported JSON formats:
// 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"
}
}{
"home.welcome": "Welcome!",
"home.subtitle": "Get started with {{appName}}",
"button.submit": "Submit"
}{
"home": {
"welcome": "Welcome!",
"subtitle": "Get started with {{appName}}"
},
"button": {
"submit": "Submit"
}
}{
"home": {
"welcome": "Welcome!",
"subtitle": "Get started with {{appName}}"
}
}/* Welcome message */
"home.welcome" = "Welcome!";
/* Homepage subtitle with app name placeholder */
"home.subtitle" = "Get started with %@";
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Welcome message -->
<string name="home.welcome">Welcome!</string>
<!-- Homepage subtitle with app name placeholder -->
<string name="home.subtitle">Get started with %1$s</string>
</resources>{
"@@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"
}
}
}
}# 1. Authenticate
langctl auth lc_your_api_key_here
# 2. 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.submit
# 5. 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/# 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 --publish
# 3. Verify imports
langctl keys list my-app --published
langctl projects stats my-app# 1. Invite team members
langctl team invite developer@example.com --role member
langctl team invite manager@example.com --role admin
# 2. Check invitations
langctl team invitations --pending
# 3. Manage roles
langctl team update-role developer@example.com admin
# 4. View team
langctl team list# Export for all platforms
PROJECT="my-app"
LANG="en"
# Web (i18next)
langctl export $PROJECT -l $LANG -f i18n-json -o ./src/locales/$LANG.json
# iOS
langctl export $PROJECT -l $LANG -f ios-strings -o ./ios/$LANG.lproj/Localizable.strings
# Android
langctl export $PROJECT -l $LANG -f android-xml -o ./android/res/values/strings.xml
# Flutter
langctl export $PROJECT -l $LANG -f flutter-arb -o ./lib/l10n/app_$LANG.arbAutomated translation sync workflow:
name: Sync Translations
on:
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 pushsync-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:
- schedulesFROM node:18-alpine
RUN 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-
Use modules to organize keys by feature:
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
-
Follow naming conventions:
module.screen.element auth.login.title home.hero.subtitle -
Add descriptions to keys:
langctl keys create app button.submit \ --description "Primary action button across the app" \ --value-en "Submit"
-
Create keys unpublished (draft mode)
-
Add translations for all languages
-
Review and test translations
-
Publish when ready:
langctl keys publish my-app key1 key2 key3
-
Export published translations only:
langctl export my-app -l en
-
Use appropriate roles:
viewer- Stakeholders, reviewers (read-only)member- Translators, content writersadmin- Project managers, team leads
-
Regular access reviews:
langctl team list langctl team invitations
-
Never commit API keys to version control
-
Use environment variables:
export LANGCTL_API_KEY="lc_..." langctl auth $LANGCTL_API_KEY
-
Rotate keys periodically from app.langctl.com
-
Use different keys for different environments:
- Development key for local work
- CI/CD key for automated workflows
- Production key for releases
"Not authenticated" error:
# 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
"Project not found" error:
# Check project slug (not name)
langctl projects list
# Use the slug shown in the list
langctl keys list correct-slug-hereCannot remove language:
- Cannot remove the default language
- Change default language first:
langctl projects update my-app --default-language en langctl projects remove-language my-app fr
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:
langctl keys list my-app --published
- Or include unpublished:
langctl export my-app -l en --include-unpublished
If experiencing connectivity problems:
- Check your internet connection
- Verify you're not behind a restrictive firewall
- Try again in a few moments
- Contact support if issue persists
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 <new-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.
- β macOS (Apple Silicon & Intel)
- β Linux (x64, ARM64)
- β Windows (x64, ARM64)
- β Node.js 16.0.0 or higher
Tired of expensive translation management tools? Langctl offers:
- β Free to start - No credit card required
- β 90% cheaper than enterprise alternatives
- β Developer-first - Built for your workflow
- β AI-powered - Context-aware translations
- β Open source CLI - Inspect, fork, contribute
See pricing and compare features β
- π Website - Features, pricing, and comparisons
- π Full Documentation - Guides, tutorials, and best practices
- π― Quick Start Tutorial - Step-by-step walkthrough
- π‘ Integration Guides - React, Angular, Vue, iOS, Android, Flutter
- π Dashboard - Manage translations visually
- π¬ Get Support - Email us at hello@langctl.com
- π Report Issues - Bug reports and feature requests
We welcome contributions! This is an open-source project and we'd love your help making it better.
MIT License - see LICENSE file for details.
Copyright Β© 2026 Litcode Private Limited. All rights reserved.
Built with β€οΈ by the Langctl team
Making translation management simple, fast, and developer-friendly.