# Crowdin CLI

> Guides correct usage of Crowdin CLI - the `crowdin` command that syncs localization files between a local project and Crowdin. Use whenever the user runs, scripts, or debugs `crowdin` commands, creates or edits a crowdin.yml configuration, uploads sources, downloads translations, checks translation status, auto-translates a project, wires localization into CI/CD, or migrates scripts from CLI v4 to v5 - even if they just say "sync translations" or "push strings to Crowdin" without naming the CLI.

- Skill: `crowdin/crowdin-cli` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add crowdin/crowdin-cli`
- Raw SKILL.md: https://api.skillmd.com/api/skills/crowdin/crowdin-cli/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: crowdin (https://skillmd.com/u/crowdin)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/crowdin/crowdin-cli

---


# 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](references/migrating-from-v4.md) for the differences.

Full documentation: https://crowdin.github.io/crowdin-cli

## Install

```bash
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](references/configuration.md#installation) 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_url` is `https://api.crowdin.com` (the default — no need to set it).
- Crowdin Enterprise: create it in **Account Settings → Access Tokens**. `base_url` must be set to `https://{organization}.api.crowdin.com`.
- The project ID is numeric — get it with `crowdin project list` once a token is configured, or from the project page in Crowdin.

Credentials resolve in this priority order (highest wins):

1. CLI flags: `-T/--token`, `-i/--project-id`, `--base-url`, `--base-path`
2. Identity file: `--identity <path>`, or `~/.crowdin.yml` / `~/.crowdin.yaml` if present
3. `*_env` keys in the config file (`api_token_env: MY_VAR` reads `$MY_VAR`)
4. Literal keys in the config file (`api_token: "..."`)
5. `CROWDIN_PERSONAL_TOKEN`, `CROWDIN_PROJECT_ID`, `CROWDIN_BASE_PATH`, `CROWDIN_BASE_URL` environment 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:

```yaml
"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%"
```

- `source` is a glob for local source files (relative to `base_path`); `translation` tells Crowdin where exported translations land, using placeholders like `%two_letters_code%`, `%locale%`, `%original_file_name%`, `%original_path%`, `%file_name%`.
- `preserve_hierarchy: true` keeps the local directory structure in Crowdin; without it, the common parent directory is stripped.
- One `files` entry per file group; each entry can add `ignore`, `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](references/configuration.md).

Before the first upload, verify the config instead of debugging a wrong upload after the fact:

```bash
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.

```bash
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:

```bash
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](references/commands.md#auto-translate).

## Output for scripts and agents

The global `-o/--output` option changes any command's output format:

- `-o json` — machine-readable JSON; pipe into `jq` or parse from a script
- `-o toon` — [Token-Oriented Object Notation](https://github.com/toon-format/toon), 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 `--plain` flag)

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.

```bash
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](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](../crowdin-context-cli/SKILL.md) 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`; keep `project_id` in the committed `crowdin.yml` (it is not sensitive).
- Typical pipeline: `crowdin upload sources` on merge to the main branch; `crowdin download translations` on a schedule or before release, followed by a commit/PR of the updated files.
- For GitHub Actions prefer the official [crowdin/github-action](https://github.com/crowdin/github-action), which wraps this CLI — covered by the [github-action](../github-action/SKILL.md) 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-incomplete` exits non-zero when the project isn't fully translated — a ready-made release gate.

## Related skills

- [crowdin-context-cli](../crowdin-context-cli/SKILL.md) — `crowdin context download/upload` for AI context enrichment
- [croql](../croql/SKILL.md) — CroQL expressions for `--croql` filters on string commands
- [crowdin-api-client](../crowdin-api-client/SKILL.md) — the JS/TS API client, when a CLI command doesn't cover the need

