v0.1.0 · open source, MIT · written in Rust

Translate anything,
right from your terminal.

Zellig is a tiny Rust CLI that speaks 200 languages — on-device with NLLB, through a cloud translation service, or via your favourite LLM. Strings, files, whole directories. It preserves your formatting and stays out of the way.

$ curl -fsSL https://raw.githubusercontent.com/kodaskills/zellig/main/install.sh | sh
or cargo install zellig
or docker run --rm ghcr.io/kodaskills/zellig
· macOS · Linux · Windows · Docker · 8 MB binary · zero runtime dependencies ·
~/projects/site — zellig
What it does

Built for the way localization actually happens.

One small binary that pulls together the three jobs you used to glue together with shell scripts: machine translation, LLMs, and file-format-aware batch processing.

01

Local, by default

Ship NLLB-200 (600M / 1.3B / 3.3B) right next to your binary. Everything runs on-device — no API keys, no rate limits, no data leaving your machine.

ct2rs · CTranslate2 · cpu · cuda
02

20+ LLM backends

Plug Zellig into Anthropic, OpenAI, Gemini, xAI, DeepSeek, Groq, Ollama, or any OpenAI-compatible endpoint. Bring your own prompt; cache by default.

openai · anthropic · ollama · …
03

10 translation services

DeepL, Google, Yandex, Azure, LibreTranslate, Bergamot, Baidu, Youdao, QQ, Lingva — picked at runtime per file, per language, or per glossary.

drop-in · auth via env · rate-aware
04

Formats it respects

Walks directories, filters by extension, and keeps your structure intact. PO comments, XLIFF metadata, JSON keys, TOML tables, YAML anchors, Markdown blocks.

po · xliff · json · toml · yaml · md
Formats

Speaks your file formats, not just your strings.

.po Gettext catalogs

Comments, plurals, msgctxt, fuzzy flags — preserved. Never overwrites an existing msgstr unless you ask.

.xliff XLIFF 1.2 & 2.0

Trans-unit attributes, inline tags, and state machinery survive the round trip.

.json JSON / i18next

Nested keys, ICU plurals, interpolation tokens like {{name}} stay verbatim.

.toml TOML

Tables, arrays of tables, inline strings — translated values keep their key paths and order.

.yaml YAML / Rails

Anchors, aliases, and i18n.yml conventions are honoured; flow style preserved.

.md Markdown / MDX

Code fences, links, and front-matter are left alone. Prose gets translated. JSX nodes opt-in.

Backends

One CLI. Thirty-something ways to translate.

Switch backends per command, per directory, or per language pair. Zellig caches every translation by content hash, so re-runs are free and deterministic.

31 supported backends

Local

1 engine

Run on your laptop or a CI box. No network, no keys, no cost.

nllb-200 ct2rs

AI / LLMs

20+ providers

Any chat-completions endpoint. Prompts and glossaries are first-class.

openaianthropicgemini xaigroqdeepseek cohereollamaollama-cloud openai-responsesopencode-gotogether fireworksnebiusmimo zaibigmodelaliyun vertexgithub-copilot

Translation services

10 providers

Classic MT services for production-grade quality and speed.

deeplgoogleyandex azurelibretranslatebergamot baiduyoudaoqq lingva
Two modes

Scripted runs or hands-on sessions.

Use Zellig as a one-shot command in your build pipeline, or drop into an interactive TUI when you're translating by feel.

Command mode

one-shot · scriptable

Compose Zellig with the rest of Unix. Flags for everything, exit codes you can trust, scriptable output.

$ zellig translate "Where is the library?" --target fr
Où est la bibliothèque ?

$ zellig translate --dir docs/ --target ja --mode ollama
✓ 14 files translated → docs/ja/

$ zellig translate --dir ./locales \
    --target es --target de --target it \
    --mode deepl
✓ 126 files · 18,402 segments · 12.4s
  • Perfect for CI, pre-commit, and Makefile targets
  • Streaming stdin/stdout — pipe anything into it
  • Deterministic caching keyed by content hash

Interactive mode

tui · exploratory

A small TUI with multi-language targeting and file loading. Built with ratatui; keyboard navigation, live preview, and syntax-coloured output.

$ zellig tui

 ◆ zellig                                      Translate
────────────────────────────────────────────────────────
 Models │ Languages │ Config │ Translate │ File │ Detect
────────────────────────────────────────────────────────
╭─ Source ↔ ─────────────────╮╭─ Target ───────────────╮
│  English                   ││  French                │
╰────────────────────────────╯╰────────────────────────╯
╭─ Text ───────────────────────────────────────────────╮
│  The early bird catches the worm.                    │
╰──────────────────────────────────────────────────────╯
╭─ Translation ────────────────────────────────────────╮
│  Le lève-tôt attrape le ver.                         │
╰──────────────────────────────────────────────────────╯
────────────────────────────────────────────────────────
  Type  [Tab]=lang  [Enter]=translate  [Esc]=menu
  • Switch backend/target/glossary inline with :commands
  • Side-by-side diff when re-translating
  • Save sessions as reusable recipes
Numbers

Small binary. Generous appetite.

200+ langs covered by NLLB

From Asturian to Zulu — pivot through English when needed.

180ms local p50, M2

A 50-word string, NLLB-200 600M, cold cache.

8MB stripped binary

Single static binary, no Python, no node_modules.

8× concurrent by default

Tokio async fan-out across target languages and batches; backend-aware rate limits.

Roadmap

What's next.

v0.1 May 2026 current

Foundation

Directory walker, 10 translation services, 20+ AI/LLM backends, interactive TUI, content-hash caching, and 6 file formats.

v0.2 Jul 2026 planned

Glossaries + streaming

First-class glossary files, do-not-translate rules, and streaming output for long documents.

v0.3 Q4 2026 planned

VS Code extension

In-editor preview, side-by-side diff, and one-click backend switching.

v0.4 2027 planned

Server mode

Run Zellig as a lightweight HTTP service for batch APIs and CI fan-out.

v1.0 2027 planned

Stable

Frozen CLI, semver guarantees, long-term support for the v1 plugin ABI.

Community

Built in the open, with friends.

Open source & free

Zellig is MIT-licensed and developed in the open at github.com/kodaskills/zellig.
Issues, pull requests, and backend plugins all welcome.

Ways to contribute

+ you?
  • Add a new file format (csv / resx / …)
  • Add a translation backend
  • Improve the documentation
Common questions

Things people ask before installing.

Yes. Zellig runs NLLB-200 (600M, 1.3B, 3.3B) on-device via ct2rs / CTranslate2. After the first zellig models --download JustFrederik/nllb-200-distilled-600M-ct2-int8, everything happens on your machine — no network calls, no telemetry. For GPU acceleration, build with --features cuda and set device = "cuda" in [local] — the same binary runs on CPU-only machines too. Output quality can be tuned with repetition_penalty and no_repeat_ngram_size in your config.

By default, Zellig is conservative. Existing msgstrs, populated XLIFF targets, and already-localized JSON keys are skipped.

Yes — implement the Translator trait in Rust (around 60 lines) and wire it into your config. The plugin interface is stable and well-documented.

Zellig is at 0.1.x — early but functional. The CLI surface and file-format adapters are working; LLM prompts and the plugin ABI may still shift before 1.0. Pin your version in CI.

Those are excellent and Zellig stands on their shoulders. The differences: a single static binary, first-class LLM and local-model backends, content-hash caching, and an interactive REPL. Pick whichever fits your team.

Yes — an official image (including the local NLLB-200 backend) is published to GHCR after every release:

docker run --rm ghcr.io/kodaskills/zellig translate "Hello" --target fr

To translate a local directory, mount it as a volume:

docker run --rm -v "$(pwd):/data" ghcr.io/kodaskills/zellig translate --dir /data/locales --target es

A docker-compose.yml is included in the repo with a dev profile (cargo-watch hot-reload) and a prod profile for one-off runs. See the repository for details.

Glossary support is planned for v0.2. Today, JSON and YAML formats preserve interpolation tokens like {{name}} verbatim.