Crowdin CLI
Crowdin CLI is the command-line tool for managing and synchronizing localization resources with a Crowdin project. It ships as a single self-contained binary — no Java or other runtime required.
Check what's installed with crowdin --version. If it prints 4.x or a Java error, the user is on the legacy CLI — commands below still mostly apply, but see references/migrating-from-v4.md for the differences.
Full documentation: https://crowdin.github.io/crowdin-cli
Install
npm install -g @crowdin/cli
Also available via Homebrew (brew tap crowdin/crowdin && brew install crowdin@5), WinGet, Chocolatey, Docker (crowdin/cli), Linux package repositories, and as a standalone binary — see references/configuration.md for every option.
Authenticate
The CLI needs a personal access token and (for most commands) a project ID:
- crowdin.com: create the token in Settings → API (
https://crowdin.com/settings#api-key).base_urlishttps://api.crowdin.com(the default — no need to set it). - Crowdin Enterprise: create it in Account Settings → Access Tokens.
base_urlmust be set tohttps://{organization}.api.crowdin.com. - The project ID is numeric — get it with
crowdin project listonce a token is configured, or from the project page in Crowdin.
Credentials resolve in this priority order (highest wins):
- CLI flags:
-T/--token,-i/--project-id,--base-url,--base-path - Identity file:
--identity <path>, or~/.crowdin.yml/~/.crowdin.yamlif present *_envkeys in the config file (api_token_env: MY_VARreads$MY_VAR)- Literal keys in the config file (
api_token: "...") CROWDIN_PERSONAL_TOKEN,CROWDIN_PROJECT_ID,CROWDIN_BASE_PATH,CROWDIN_BASE_URLenvironment variables
.env files in the working directory are loaded automatically, so CROWDIN_PERSONAL_TOKEN can live there. Never write a real token into crowdin.yml if the file is committed — use api_token_env or the CROWDIN_PERSONAL_TOKEN variable instead.
crowdin init sets up a project interactively, including browser-based authorization — but a browser-issued token expires after 30 days, so for CI and long-lived automation use a personal access token.
Configure — crowdin.yml
Commands read crowdin.yml (or crowdin.yaml) from the current directory; override with -c/--config <path>. Minimal real-world example:
"project_id": "123456"
"api_token_env": "CROWDIN_PERSONAL_TOKEN"
"base_path": "."
"preserve_hierarchy": true
files:
- source: "/src/locales/en/**/*.json"
translation: "/src/locales/%two_letters_code%/**/%original_file_name%"
sourceis a glob for local source files (relative tobase_path);translationtells Crowdin where exported translations land, using placeholders like%two_letters_code%,%locale%,%original_file_name%,%original_path%,%file_name%.preserve_hierarchy: truekeeps the local directory structure in Crowdin; without it, the common parent directory is stripped.- One
filesentry per file group; each entry can addignore,dest,type,update_option,labels,excluded_target_languages,languages_mapping, and more.
The full reference — all placeholders, per-entry options, language mapping, multiple file groups — is in references/configuration.md.
Before the first upload, verify the config instead of debugging a wrong upload after the fact:
crowdin config lint # validate syntax
crowdin config sources # list local files matched by each source pattern
crowdin config translations # list translation paths that will be produced
crowdin upload sources --dryrun
Core workflow
The everyday cycle is: upload sources → translate → download translations.
crowdin upload sources # push local source files (alias: crowdin push)
crowdin status # translation & proofreading progress per language
crowdin auto-translate --method tm # optional: pre-fill via TM, MT, or AI
crowdin download translations # pull completed translations (alias: crowdin pull)
Useful variants:
crowdin upload sources --cache # skip unchanged files (checksum cache)
crowdin upload sources --delete-obsolete # remove files from Crowdin that no longer exist locally
crowdin upload translations # import existing local translations
crowdin download translations -l uk -l fr # only some languages
crowdin download translations --skip-untranslated-strings
crowdin download sources # pull sources back from Crowdin
Everything is branch-aware: pass -b <name> to scope upload/download/status to a Crowdin branch (create it with crowdin branch add).
auto-translate (v4's pre-translate) applies TM (--method tm), machine translation (--method mt --engine-id <id>), or AI (--method ai --ai-prompt <id>), with fine-grained control: --scope untranslated|translated|all, --skip-approved-translations, --label/--exclude-label, --replace-translations-option, --translation-modified-before, and more — see references/commands.md.
Output for scripts and agents
The global -o/--output option changes any command's output format:
-o json— machine-readable JSON; pipe intojqor parse from a script-o toon— Token-Oriented Object Notation, same data as JSON at a fraction of the size; prefer this when the consumer is an LLM-o plain— minimal processable text (v4's--plainflag)
In json and toon modes stdout carries nothing but data — no spinners, colors, or decorative messages — so output is safe to parse. When running the CLI as an agent, default to -o toon for lists you only need to read and -o json when a script must parse the result.
crowdin file list -o json | jq -r '.[].path'
crowdin status -o toon
Exit codes are stable and meaningful — branch on them rather than parsing error text:
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | General error |
| 2 | Validation error (bad config or arguments) |
| 101 | Authorization error (bad/expired token) |
| 102 | Not found |
| 103 | Forbidden |
| 129 | Rate limit exceeded |
Mutating file commands accept --dryrun to preview what would happen. Add -v/--verbose when diagnosing; --no-progress/--no-colors clean up logs in CI (json/toon modes already imply this).
Command map
21 top-level commands; most have subcommands. Full option-level reference: references/commands.md.
| Command | Purpose |
|---|---|
upload (push) |
Upload sources / translations per crowdin.yml |
download (pull) |
Download translations / sources per crowdin.yml |
init |
Generate crowdin.yml interactively |
status |
Translation & proofreading progress |
auto-translate |
Pre-fill translations via TM / MT / AI |
file |
Direct file ops without config patterns (list, upload, download, delete) |
string |
Manage source strings (list, add, edit, delete; CroQL filters) |
branch |
Manage branches (add, list, clone, merge, edit, delete) |
task |
Create and list translation/proofreading tasks |
tm |
Translation memories (list, upload, download) |
glossary |
Glossaries (list, upload, download) |
bundle |
Export bundles (list, add, download, clone, browse) |
distribution |
Content distributions (add, list, edit, release) |
screenshot |
Screenshots for context (list, upload, delete) |
comment |
String comments and issues (list, add, resolve) |
label |
Labels (list, add, delete) |
language |
List project/supported languages |
project |
List, add, browse projects |
config |
Validate config, preview matched sources/translations |
app |
Install/uninstall Crowdin apps |
context |
AI context for strings — covered by the crowdin-context-cli skill |
Shell completion: source <(crowdin complete zsh) (also bash, fish, powershell).
CI/CD
- Store the token as a CI secret exposed as
CROWDIN_PERSONAL_TOKEN; keepproject_idin the committedcrowdin.yml(it is not sensitive). - Typical pipeline:
crowdin upload sourceson merge to the main branch;crowdin download translationson a schedule or before release, followed by a commit/PR of the updated files. - For GitHub Actions prefer the official crowdin/github-action, which wraps this CLI — covered by the github-action skill.
- The CLI never prompts when all required values are provided; a missing value fails with exit code 2 rather than hanging.
crowdin status --fail-if-incompleteexits non-zero when the project isn't fully translated — a ready-made release gate.
Related skills
- crowdin-context-cli —
crowdin context download/uploadfor AI context enrichment - croql — CroQL expressions for
--croqlfilters on string commands - crowdin-api-client — the JS/TS API client, when a CLI command doesn't cover the need