@lingo.dev/cli
@lingo.dev/cli ships your source content to a localization engine, which translates it server-side, and writes the outputs back to disk — in the same command with --wait, or later with lingo pull. It's the replacement for the legacy npx lingo.dev flow — same project, fundamentally different architecture.
What changed vs. the legacy CLI#
The legacy CLI (npx lingo.dev run) extracted strings, called an LLM directly from your machine, and wrote files in one pass on your machine. The current CLI splits the work into push and pull:
lingo pushuploads sources to your engine, kicks off a server-side workflow, and either waits for completion or returns immediately with a run IDlingo pullfetches outputs from the most recent push — works even if you closed the terminal mid-translation, as long as you pull on the same machine, from the same checkout- A lockfile (
.lingo/lock.json) tracks the last-known-server version of every target so conflict detection can flag local edits before they get overwritten
This unlocks something the legacy CLI couldn't do: long-running translations without a hanging terminal — push, close the terminal, and pull the results later.
Waiting for results#
lingo push uploads sources, starts the server-side workflow, and exits as soon as the run is submitted — it doesn't wait for the translations or write them. Collect the outputs with lingo pull, or pass --wait (-w) to do everything in one command.
lingo push # submit the run and exit (default)
lingo pull # later: re-attach to the most recent push and download its outputs
lingo push --wait # submit, wait, and write outputs in one command--wait(-w) blocks until the workflow finishes and writes outputs in the same command.lingo pullre-attaches to the most recent push for this project and downloads its outputs — works even after you closed the terminal. Run state is per-machine at~/.lingo/runs/<project-hash>.json, keyed by the project path, sopullresumes on the same machine, from the same checkout.
Auth: both commands read LINGO_API_KEY (or --api-key, or a lingo login session). In CI, set LINGO_API_KEY and nothing else is needed.
push modes#
| Command | Mode | When |
|---|---|---|
lingo push | Incremental — diffs source vs .lingo/lock.json, translates only new/changed keys into existing targets, preserves the rest | Every routine run (add --wait in CI) |
lingo push --backfill-missing | Bootstrap — fills target FILES that don't exist yet | First push, or after adding a new locale |
lingo push --force | Full re-translate — overwrites every target (incl. manual edits); --yes/-y skips the prompt | Rarely (e.g. after a glossary/engine change) |
--backfill-missing is a bootstrap flag. It does a scoped fresh request and only adds whole target files that are missing — it does NOT translate newly-added keys into already-translated files (the run reports "already up-to-date" and the key is skipped). For ongoing edits use plain lingo push.
Editing translations by hand#
Plain lingo push preserves manual edits per key:
- Edit a target string (its source unchanged) → that string is kept; other keys keep updating.
- The source behind an edited key changes → a fresh translation is generated for that key, replacing the manual edit.
- A new source key is added → translated and added, even into files with manual edits.