A next-generation command-line interface for DeepL translation and writing enhancement
DeepL CLI is a comprehensive, developer-friendly command-line tool that integrates DeepL's powerful translation API and cutting-edge Write API for grammar and style enhancement. Built with TypeScript and designed for modern development workflows.
π Key Features
- π Translation - High-quality translation using DeepL's next-gen LLM
- π Document Translation - Translate PDF, DOCX, PPTX, XLSX with formatting preservation
- ποΈ Voice Translation - Real-time speech translation via WebSocket streaming (Voice API)
- π Watch Mode - Real-time file watching with auto-translation
- βοΈ Writing Enhancement - Grammar, style, and tone suggestions (DeepL Write API)
- πΎ Smart Caching - Local SQLite cache with LRU eviction
- π― Context-Aware - Preserves code blocks, variables, and formatting
- π¦ Batch Processing - Translate multiple files with parallel processing
- π° Cost Transparency - Track actual billed characters for budget planning
- π§ Developer Workflows - Git hooks, CI/CD integration
- π Privacy-First - Local caching, no telemetry, secure key storage
For security policy and vulnerability reporting, see SECURITY.md.
π Table of Contents
- Installation
- Quick Start
- Global Options
- Usage
- Core Commands: Translation | Writing Enhancement | Voice Translation
- Resources: Glossaries
- Workflow: Watch Mode | Git Hooks
- Configuration: Setup Wizard | Authentication | Configure Defaults | Cache Management | Style Rules
- Information: Usage Statistics | Language Detection | Languages | Shell Completion
- Administration: Admin API
- Development
- Architecture
- Contributing
- License
π¦ Installation
From npm (Coming Soon)
From Source
# Clone the repository git clone https://github.com/DeepLcom/deepl-cli.git cd deepl-cli # Install dependencies npm install # Build the project npm run build # Link for global usage npm link # Verify installation deepl --version # Output: 1.0.0
Note: This project uses
better-sqlite3for local caching, which requires native compilation. Ifnpm installfails with build errors, ensure you have:
- macOS: Xcode Command Line Tools (
xcode-select --install)- Linux:
python3,make, andgcc(apt install python3 make gcc g++)- Windows: Visual Studio Build Tools or
windows-build-tools(npm install -g windows-build-tools)
π Quick Start
1. Get Your DeepL API Key
Sign up for a DeepL API account and get your authentication key.
2. Set Up Your Environment
Use the interactive setup wizard:
Or set your API key directly:
deepl auth set-key YOUR_API_KEY # Recommended: pipe key from stdin to avoid exposing it in process listings echo "YOUR_API_KEY" | deepl auth set-key --from-stdin
Or use an environment variable:
export DEEPL_API_KEY=YOUR_API_KEY3. Translate Your First Text
deepl translate "Hello, world!" --to es # Output: # Translation (ES): # Β‘Hola, mundo!
π§ Global Options
DeepL CLI supports global flags that work with all commands:
| Flag | Short | Description |
|---|---|---|
--version |
-V |
Show version number |
--quiet |
-q |
Suppress non-essential output |
--verbose |
-v |
Show extra information |
--config FILE |
-c |
Use alternate configuration file |
--no-input |
Disable all interactive prompts (abort instead of prompting) |
Verbose Mode
The --verbose (or -v) flag shows extra information such as detected source language, timing, and cache status. Useful for debugging and understanding translation behavior.
$ deepl --verbose translate "Hello" --to esQuiet Mode
The --quiet (or -q) flag suppresses all non-essential output, showing only errors and essential results. Perfect for scripts, CI/CD pipelines, and automation.
# Normal mode - shows informational messages $ deepl translate "Hello" --to es Hello # Quiet mode - cleaner output $ deepl --quiet translate "Hello" --to es Hola # Suppress progress indicators in batch operations $ deepl --quiet translate docs/ --to es --output docs-es/ # Shows only final statistics, no spinners or progress updates
What's suppressed in quiet mode:
- β Informational messages (
API Key: ...) - β Success confirmations (
β Cache enabled) - β Progress spinners and status updates
- β Decorative output
What's always shown:
- β Errors and critical warnings
- β Essential command output (translation results, JSON data, statistics)
Use cases:
- CI/CD pipelines: Clean output for log parsing
- Scripting: Extract just the translation result
- Automation: Reduce noise in automated workflows
- Parsing: Easier to parse machine-readable output
# Example: Use in scripts TRANSLATION=$(deepl --quiet translate "Hello" --to es) echo "Result: $TRANSLATION" # Result: Hola # Example: CI/CD pipeline deepl --quiet translate docs/ --to es,fr,de --output i18n/ # Returns exit code 0 on success, shows only errors if they occur
See docs/API.md#global-options for complete documentation.
Command Suggestions
Mistype a command? The CLI suggests the closest match:
$ deepl transalte "Hello" --to es # Error: Unknown command 'transalte'. Did you mean 'translate'?
Custom Configuration Files
The --config (or -c) flag allows you to use alternate configuration files for different projects, environments, or accounts:
# Use work configuration $ deepl --config ~/.deepl-work.json translate "Hello" --to es # Use project-specific configuration $ deepl --config ./project/.deepl.json translate docs/ --to fr --output docs-fr/ # Use test environment configuration $ deepl -c /path/to/test-config.json usage
Use cases:
- Multiple API keys: Switch between free and paid accounts
- Project isolation: Different settings per project (glossaries, formality defaults, etc.)
- Team configurations: Share standardized configs via version control
- Environment separation: Separate configs for dev/staging/production
- Testing: Use test configurations without affecting default settings
Precedence: --config > DEEPL_CONFIG_DIR > legacy ~/.deepl-cli/ > XDG directories (see below).
Configuration Paths
The CLI follows the XDG Base Directory Specification:
| Priority | Condition | Config path | Cache path |
|---|---|---|---|
| 1 | DEEPL_CONFIG_DIR set |
$DEEPL_CONFIG_DIR/config.json |
$DEEPL_CONFIG_DIR/cache.db |
| 2 | ~/.deepl-cli/ exists |
~/.deepl-cli/config.json |
~/.deepl-cli/cache.db |
| 3 | XDG env vars set | $XDG_CONFIG_HOME/deepl-cli/config.json |
$XDG_CACHE_HOME/deepl-cli/cache.db |
| 4 | Default | ~/.config/deepl-cli/config.json |
~/.cache/deepl-cli/cache.db |
Existing ~/.deepl-cli/ installations continue to work with no changes needed.
See docs/API.md#global-options for more details.
π Usage
Translation
Basic Text Translation
# Simple translation deepl translate "Hello world" --to ja # Translation (JA): # γγγ«γ‘γ―δΈη # Specify source language explicitly deepl translate "Bonjour" --from fr --to en # Translation (EN): # Hello # Multiple target languages deepl translate "Good morning" --to es,fr,de # Translation (ES): # Buenos dΓas # # Translation (FR): # Bonjour # # Translation (DE): # Guten Morgen # Read from stdin echo "Hello world" | deepl translate --to es cat input.txt | deepl translate --to ja
File Translation
Text Files: .txt, .md, .html, .htm, .srt, .xlf, .xliff
Structured Files (i18n): .json, .yaml, .yml
Structured files are parsed to extract only string values. Keys, nesting, non-string values (numbers, booleans, null), indentation, and YAML comments are all preserved. Ideal for translating i18n locale files.
# Translate a JSON locale file deepl translate en.json --to es --output es.json # Translate a YAML locale file (comments preserved) deepl translate en.yaml --to de --output de.yaml # Multiple targets deepl translate locales/en.json --to es,fr,de --output locales/
Smart Caching for Text Files:
Small text-based files (under 100 KB) automatically use the cached text translation API for faster performance and reduced API calls. Larger files automatically fall back to the document translation API (not cached).
- Cached formats:
.txt,.md,.html,.htm,.srt,.xlf,.xliff(files under 100 KB only) - Structured formats:
.json,.yaml,.ymlβ parsed and translated via batch text API (no size limit) - Large file fallback: Files β₯100 KB use document API (not cached, always makes API calls)
- Binary formats:
.pdf,.docx,.pptx,.xlsxalways use document API (not cached) - Performance: Only small text files (<100 KB) benefit from instant cached translations
- Cost savings: Only small text files avoid repeated API calls
# Single file translation (uses cache for small text files) deepl translate README.md --to es --output README.es.md # Translated README.md to 1 language(s): # [ES] README.es.md # Multiple target languages (creates README.es.md, README.fr.md, etc.) deepl translate docs.md --to es,fr,de --output ./translated/ # Translated docs.md to 3 language(s): # [ES] ./translated/docs.es.md # [FR] ./translated/docs.fr.md # [DE] ./translated/docs.de.md # With code preservation (preserves code blocks in markdown) deepl translate tutorial.md --to ja --output tutorial.ja.md --preserve-code # Large text file (over 100 KiB) - automatic fallback with warning deepl translate large-document.txt --to es --output large-document.es.txt # β File exceeds 100 KiB limit for cached translation (150.5 KiB), using document API instead # Translated large-document.txt to 1 language(s): # [ES] large-document.es.txt
Document Translation
Supported Document Formats: .pdf, .docx, .doc, .pptx, .xlsx, .html, .htm, .txt, .srt, .xlf, .xliff, .jpg, .jpeg, .png
Translate complete documents while preserving formatting, structure, and layout:
# Translate PDF document deepl translate document.pdf --to es --output document.es.pdf # Uploading document... # Document queued for translation... # Translating document (est. 5s remaining)... # Downloading translated document... # β Document translated successfully! # Translated document.pdf -> document.es.pdf # Billed characters: 1,234 # Translate PowerPoint presentation deepl translate presentation.pptx --to fr --output presentation.fr.pptx # Translate Excel spreadsheet deepl translate report.xlsx --to de --output report.de.xlsx # Translate HTML file deepl translate website.html --to ja --output website.ja.html # With formality setting deepl translate contract.pdf --to de --formality more --output contract.de.pdf # Specify source language deepl translate document.pdf --from en --to es --output document.es.pdf # Convert PDF to DOCX during translation (ONLY supported conversion) deepl translate document.pdf --to es --output-format docx --output document.es.docx # Translates PDF to Spanish and converts to editable Word format # Note: DeepL API only supports PDF β DOCX conversion # All other format conversions (DOCXβPDF, HTMLβTXT, etc.) are NOT supported # See examples/06-document-format-conversion.sh for details
Document Translation Features:
- β Preserves Formatting - Maintains fonts, styles, colors, and layout
- β Format Conversion - PDF β DOCX conversion only (convert PDFs to editable Word documents)
- β Progress Tracking - Real-time status updates during translation
- β Large Files - Handles documents up to 10MB (PDF) or 30MB (other formats)
- β Cost Tracking - Shows billed characters after translation
- β Async Processing - Documents are translated on DeepL servers with polling
Supported Formats:
.pdf- PDF documents.docx,.doc- Microsoft Word.pptx- Microsoft PowerPoint.xlsx- Microsoft Excel.html,.htm- HTML files.txt- Plain text files.srt- Subtitle files.xlf,.xliff- XLIFF localization files.jpg,.jpeg- JPEG images.png- PNG images
Note: Document translation uses DeepL's async translation API. The CLI automatically handles upload, polling, and download. Translation time varies based on document size and complexity.
Batch Translation (Directory Processing)
Translate multiple files in parallel with progress indicators:
# Translate all files in a directory deepl translate ./docs --to es --output ./docs-es # Scanning files... # Translating files: 10/10 # β Translation complete! # # Translation Statistics: # Total files: 10 # β Successful: 10 # Translate specific file types with glob pattern deepl translate ./docs --to fr --output ./docs-fr --pattern "*.md" # Only translates markdown files # Non-recursive (current directory only) deepl translate ./docs --to de --output ./docs-de --no-recursive # Custom concurrency (default: 5) deepl translate ./large-docs --to ja --output ./large-docs-ja --concurrency 10 # Faster processing with more parallel translations
Performance Optimization:
The CLI automatically optimizes batch translations by grouping multiple texts into single API requests (up to 50 texts per batch). This significantly reduces API overhead and improves translation speed compared to translating texts individually.
- β Automatic batching - Groups translations into efficient batches
- β Cache-aware - Only translates uncached texts
- β Smart splitting - Respects DeepL API batch size limits (50 texts/request)
- β Parallel processing - Multiple batches processed concurrently
This optimization is automatic and transparent - no configuration needed.
Advanced Translation Options
# Preserve code blocks and variables deepl translate tutorial.md --preserve-code --to ja --output tutorial.ja.md # Preserve line breaks and whitespace formatting deepl translate document.txt --preserve-formatting --to es --output document.es.txt # Enable document minification for PPTX/DOCX (reduces file size) deepl translate presentation.pptx --enable-minification --to de --output presentation.de.pptx # Set formality level (default, more, less, prefer_more, prefer_less, formal, informal) deepl translate "How are you?" --formality more --to de --output formal.txt # More formal: Wie geht es Ihnen? deepl translate "How are you?" --formality less --to de --output casual.txt # Less formal: Wie geht's? # Add context for better translation quality (helps with ambiguous terms) deepl translate "bank" --context "This document is about financial institutions" --to es # Translation considers financial context β "banco" (financial institution) deepl translate "bank" --context "This document is about rivers and geography" --to es # Translation considers geographical context β "orilla" (riverbank) # Combine context with other options deepl translate "How are you?" --context "Formal business email" --formality more --to de # Choose model type for quality vs. speed trade-offs deepl translate "Long document text..." --to ja --model-type quality_optimized # Best translation quality (default) deepl translate "Real-time chat message" --to es --model-type latency_optimized # Faster response time, slightly lower quality deepl translate "Important email" --to de --model-type prefer_quality_optimized # Prefer quality, fall back to latency if unavailable # Custom instructions for tailored translations (repeatable, max 10) deepl translate "Click Save to confirm" --to de \ --custom-instruction "This is a software UI string" \ --custom-instruction "Keep it concise" # Combine custom instructions with other options deepl translate "Meeting at the bank" --to es \ --custom-instruction "This is about financial institutions" \ --formality more # Apply a style rule (Pro API only - get IDs with: deepl style-rules list) deepl translate "Hello" --to de --style-id "abc-123-def-456" # Custom API endpoint (for DeepL Pro accounts or testing) deepl translate "Hello" --to es --api-url https://api.deepl.com/v2 # Track actual billed characters for cost transparency deepl translate "Hello, world!" --to es --show-billed-characters # Output: # Hola, mundo! # # Billed characters: 13 # Table output format - structured view for multiple languages deepl translate "Hello, world!" --to es,fr,de --format table # ββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # β Language β Translation β # ββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ # β ES β Β‘Hola, mundo! β # β FR β Bonjour le monde! β # β DE β Hallo, Welt! β # ββββββββββββ΄βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # Table format with cost tracking (adds Characters column) deepl translate "Cost analysis" --to es,fr,de --format table --show-billed-characters --no-cache # ββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ¬βββββββββββββ # β Language β Translation β Characters β # ββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββ€ # β ES β AnΓ‘lisis de costes β 14 β # β FR β Analyse des coΓ»ts β 14 β # β DE β Kostenanalyse β 14 β # ββββββββββββ΄βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ΄βββββββββββββ # Preview what would be translated without making API calls (file/directory mode) deepl translate ./docs --to es --dry-run # Include beta languages that are not yet stable deepl translate "Hello" --to my --enable-beta-languages # Specify tag handling version (v2 improves structure handling, requires --tag-handling) deepl translate page.html --to es --tag-handling html --tag-handling-version v2 # Advanced XML/HTML tag handling (requires --tag-handling xml) # Control automatic XML structure detection deepl translate "<doc><p>Hello</p></doc>" --to es --tag-handling xml --outline-detection false # Specify tags that split sentences (like <br/> and <hr/>) deepl translate "<div>First sentence<br/>Second sentence</div>" --to es --tag-handling xml --splitting-tags "br,hr" # Preserve non-translatable content (code blocks, preformatted text) deepl translate "<doc><code>let x = 1;</code><p>Text</p></doc>" --to es --tag-handling xml --non-splitting-tags "code,pre" # Ignore specific tags and their content (scripts, styles) deepl translate page.html --to es --tag-handling xml --ignore-tags "script,style,noscript" --output page.es.html # Combine multiple XML tag handling options for fine-tuned control deepl translate complex.xml --to de --tag-handling xml \ --outline-detection false \ --splitting-tags "br,hr,div" \ --non-splitting-tags "code,pre,kbd" \ --ignore-tags "script,style" \ --output complex.de.xml
XML Tag Handling Use Cases:
Advanced XML/HTML tag handling is perfect for:
- π Localizing HTML websites while preserving structure
- π Translating technical documentation with code blocks
- π Processing custom XML formats with specific content rules
- π Protecting non-translatable content (scripts, styles, code)
- βοΈ Fine-tuned control over sentence splitting for better context
See examples/09-xml-tag-handling.sh for comprehensive XML tag handling examples with real-world scenarios.
Model Types:
quality_optimized- Best translation quality, standard latencyprefer_quality_optimized- Prefer quality, fallback to latency if unavailablelatency_optimized- Faster responses, slightly lower quality (ideal for real-time use)
See examples/08-model-type-selection.sh for a complete example with different model types.
Writing Enhancement
Improve your writing with AI-powered grammar, style, and tone suggestions using the DeepL Write API.
The --lang flag is optional. If omitted, DeepL auto-detects the language and rephrases in the original language. Generic codes en and pt are also accepted (mapped to en-US and pt-BR respectively).
# Auto-detect language (--lang is optional) deepl write "This is a sentence." # Specify language explicitly deepl write "This is a sentence." --lang en-US # Use generic language code (en maps to en-US, pt maps to pt-BR) deepl write "This is a sentence." --lang en # Apply business writing style deepl write "We want to tell you about our new product." --lang en-US --style business # Apply academic writing style deepl write "This shows that the method works." --lang en-US --style academic # Apply casual tone deepl write "That is interesting." --lang en-US --style casual # Use confident tone deepl write "I think this will work." --lang en-US --tone confident # Use diplomatic tone deepl write "Try something else." --lang en-US --tone diplomatic # Show all alternative improvements deepl write "This is good." --tone enthusiastic --alternatives # Improve files and save to output deepl write input.txt --lang en-US --output improved.txt # Edit file in place deepl write document.md --lang en-US --in-place # Interactive mode - choose from multiple style alternatives # Generates improvements with simple, business, academic, and casual styles deepl write "Text to improve." --lang en-US --interactive # Interactive mode with file deepl write document.md --lang en-US --interactive --in-place # Interactive mode with specific style (single option) deepl write "Text to improve." --lang en-US --style business --interactive # Check if text needs improvement (exit code 0 if no changes needed) deepl write document.md --lang en-US --check # Auto-fix files in place deepl write document.md --lang en-US --fix # Auto-fix with backup deepl write document.md --lang en-US --fix --backup # Show diff between original and improved deepl write file.txt --lang en-US --diff # Show diff for plain text deepl write "This text could be better." --lang en-US --diff # Bypass cache for this request deepl write "Fresh improvement please." --lang en-US --no-cache
Supported Languages:
- German (
de) - English (
en) - generic, defaults to American English - English - British (
en-GB) - English - American (
en-US) - Spanish (
es) - French (
fr) - Italian (
it) - Portuguese (
pt) - generic, defaults to Brazilian Portuguese - Portuguese - Brazilian (
pt-BR) - Portuguese - European (
pt-PT)
Writing Styles:
simple- Easy-to-read, accessible languagebusiness- Professional, formal business toneacademic- Scholarly, research-oriented stylecasual- Relaxed, conversational toneprefer_*prefix - Apply style only if language supports it
Tones:
enthusiastic- Energetic and positivefriendly- Warm and approachableconfident- Assertive and certaindiplomatic- Tactful and considerateprefer_*prefix - Apply tone only if language supports it
Interactive Mode:
When using --interactive without specifying a style or tone, the CLI automatically generates 4 different alternatives by calling the DeepL Write API with different writing styles (simple, business, academic, casual). You can then choose which version works best for your needs:
? Choose an improvement (4 alternatives):
β― Keep original - "This text could be better improved with..."
Simple - "This text needs improvement with better..."
Business - "We recommend enhancing this text through..."
Academic - "It is advisable to improve this text via..."
Casual - "You should make this text better by..."
If you specify a style or tone with --interactive, you'll get a simple confirm/reject prompt for that single suggestion.
Note: You cannot combine --style and --tone in a single request. Choose one or the other.
Voice Translation
Translate audio in real-time using the DeepL Voice API. Supports multiple audio formats with automatic content type detection.
# Translate an audio file deepl voice recording.ogg --to de # Multiple target languages (max 5) deepl voice meeting.mp3 --to de,fr,es # Specify source language deepl voice audio.flac --to ja --from en # Pipe from stdin (content-type required) cat audio.pcm | deepl voice - --to es --content-type 'audio/pcm;encoding=s16le;rate=16000' # JSON output deepl voice speech.ogg --to de --format json # Disable live streaming (plain text at end) deepl voice speech.ogg --to de --no-stream # Set source language detection mode (auto or fixed) deepl voice speech.ogg --to de --from en --source-language-mode fixed # Customize chunking behavior deepl voice large-recording.ogg --to de --chunk-size 12800 --chunk-interval 100 # Adjust reconnection attempts (default: 3) deepl voice speech.ogg --to de --max-reconnect-attempts 5
Supported audio formats: OGG (Opus), WebM (Opus), FLAC, MP3, PCM (16kHz s16le), Matroska (Opus)
Automatic WebSocket reconnection is enabled by default (up to 3 attempts). Disable with --no-reconnect or adjust with --max-reconnect-attempts <n>.
Note: The Voice API requires a DeepL Pro or Enterprise plan.
Watch Mode
Monitor files or directories for changes and automatically translate them in real-time. Perfect for keeping documentation and localization files in sync.
# Watch a single file deepl watch README.md --to es,fr,de # Watch a directory (all supported files) deepl watch docs/ --to ja --output docs-i18n/ # Watch with pattern filtering deepl watch src/locales/ --pattern "*.json" --to es,fr,de # Watch markdown files only deepl watch docs/ --pattern "*.md" --to ja # Auto-commit translations to git deepl watch docs/ --to es --auto-commit # Custom debounce delay (default: 500ms) deepl watch src/ --to es --debounce 1000 # Preview what would be watched without starting the watcher deepl watch docs/ --to es --dry-run # Only watch git-staged files (useful in pre-commit workflows) deepl watch . --to es --git-staged # With formality and code preservation deepl watch docs/ --to de --formality more --preserve-code
Features:
- π Real-time monitoring with debouncing
- π Watch files or entire directories
- π― Glob pattern filtering (e.g.,
*.md,*.json) - π Multiple target languages
- πΎ Auto-commit to git (optional)
- π Git-staged filtering for pre-commit workflows
- β‘ Smart debouncing to avoid redundant translations
Example output:
π Watching for changes...
Path: docs/
Targets: es, fr, ja
Output: docs/translations
Pattern: *.md
π Change detected: docs/README.md
β Translated docs/README.md to 3 languages
β [es] docs/translations/README.es.md
β [fr] docs/translations/README.fr.md
β [ja] docs/translations/README.ja.md
Press Ctrl+C to stop
See examples/16-watch-mode.sh for a complete watch mode example with multiple scenarios.
Git Hooks
Automate translation validation in your git workflow with pre-commit, pre-push, commit-msg, and post-commit hooks.
# Install hooks deepl hooks install pre-commit deepl hooks install pre-push deepl hooks install commit-msg deepl hooks install post-commit # List hook installation status deepl hooks list # Show path to hook file deepl hooks path pre-commit # Uninstall a hook deepl hooks uninstall pre-commit
What the hooks do:
- pre-commit: Checks if staged files include translatable content (
.md,.txtfiles) and validates translations are up-to-date - pre-push: Validates all translations in the repository before pushing to remote
- commit-msg: Validates or augments commit messages with translation context
- post-commit: Runs post-commit translation tasks (e.g., auto-translate changed files)
Features:
- π Safe installation with automatic backup of existing hooks
- π― Only validates changed files (pre-commit)
- β‘ Lightweight and fast
- π§ Customizable hook scripts
- ποΈ Clean uninstallation with backup restoration
Hook Status Example:
$ deepl hooks list Git Hooks Status: β pre-commit installed β pre-push not installed β commit-msg not installed β post-commit not installed
Note: The hooks are generated with placeholder validation logic. You can customize them based on your project's translation workflow by editing the hook files directly at .git/hooks/pre-commit or .git/hooks/pre-push.
See examples/17-git-hooks.sh for a complete git hooks example demonstrating installation, usage, and management.
Configuration
Setup Wizard
First-time users can use the interactive setup wizard:
deepl init # Walks through: # - API key setup and validation # - Default target language selection # - Basic configuration
Authentication
# Set API key deepl auth set-key YOUR_API_KEY # β API key saved and validated successfully # Account type: DeepL API Free # Show current API key status deepl auth show # API Key: abc1...2def # Status: Valid # Clear API key deepl auth clear # β API key removed
Or use an environment variable:
export DEEPL_API_KEY=YOUR_API_KEYAPI Usage Statistics
Check your API usage to monitor character consumption:
# Show API usage statistics deepl usage # Character Usage: # Used: 123,456 / 500,000 (24.7%) # Remaining: 376,544
Note: Usage statistics help you track your DeepL API character quota and avoid exceeding limits.
See examples/23-usage-monitoring.sh for a complete usage monitoring example.
Cost Transparency:
For detailed cost tracking per translation, use the --show-billed-characters flag with the translate command (see Advanced Translation Options above). This displays the actual billed character count for each translation, helping with budget planning and cost analysis.
See examples/12-cost-transparency.sh for comprehensive cost tracking examples.
Language Detection
Detect the language of text using the DeepL API:
# Detect language of text deepl detect "Bonjour le monde" # Detected language: fr (French) # Pipe text for detection echo "γγγ«γ‘γ―" | deepl detect # JSON output for scripting deepl detect "Hola mundo" --format json # { "detected_language": "es", "language_name": "Spanish" }
Supported Languages
List all 121 supported languages grouped by category:
# Show all supported languages (both source and target) deepl languages # Source Languages: # ar Arabic # bg Bulgarian # ... # zh Chinese # # Extended Languages (quality_optimized only, no formality/glossary): # ace Acehnese # af Afrikaans # ... # # Target Languages: # ar Arabic # ... # en-gb English (British) # en-us English (American) # ... # # Extended Languages (quality_optimized only, no formality/glossary): # ace Acehnese # ... # Show only source languages deepl languages --source # Show only target languages deepl languages --target # Works without API key (shows local registry data) deepl languages
Note: Languages are grouped into three categories:
- Core (32) β Full feature support including formality and glossaries
- Regional (7) β Target-only variants:
en-gb,en-us,es-419,pt-br,pt-pt,zh-hans,zh-hant - Extended (82) β Only support
quality_optimizedmodel, no formality or glossary
See examples/24-languages.sh for a complete example.
Configure Defaults
Configuration is stored in ~/.config/deepl-cli/config.json (or ~/.deepl-cli/config.json for legacy installations; see Configuration Paths)
# View all configuration deepl config list # { # "auth": { "apiKey": "..." }, # "api": { "baseUrl": "https://api-free.deepl.com/v2", ... }, # "cache": { "enabled": true, "maxSize": 1073741824, "ttl": 2592000 }, # ... # } # Get specific value deepl config get cache.enabled # true # Set a value deepl config set defaults.targetLangs es,fr,de # β Configuration updated: defaults.targetLangs = ["es","fr","de"] # Set cache size (in bytes) deepl config set cache.maxSize 2147483648 # β Configuration updated: cache.maxSize = 2147483648 # Disable caching deepl config set cache.enabled false # Reset to defaults deepl config reset # β Configuration reset to defaults # Reset without confirmation prompt deepl config reset --yes
Proxy Configuration
DeepL CLI automatically supports HTTP and HTTPS proxies through environment variables:
# Configure HTTP proxy export HTTP_PROXY=http://proxy.example.com:8080 deepl translate "Hello" --to es # Configure HTTPS proxy export HTTPS_PROXY=https://proxy.example.com:8443 deepl translate "Hello" --to es # Configure proxy with authentication export HTTP_PROXY=http://username:password@proxy.example.com:8080 deepl translate "Hello" --to es # Both HTTP_PROXY and HTTPS_PROXY are supported (case-insensitive) export http_proxy=http://proxy.example.com:8080 export https_proxy=https://proxy.example.com:8443
Features:
- β Automatic proxy detection from environment variables
- β HTTP and HTTPS proxy support
- β Proxy authentication support
- β Follows standard proxy environment variable conventions
- β Works with all DeepL CLI commands
Note: HTTPS_PROXY takes precedence over HTTP_PROXY when both are set. The CLI automatically parses proxy URLs including authentication credentials.
Retry and Timeout Configuration
DeepL CLI includes built-in retry logic and timeout handling for robust API communication:
Automatic Retry Logic:
- Automatically retries failed requests on transient errors (5xx, network failures)
- Default: 3 retries with exponential backoff
- Does not retry on client errors (4xx - bad request, auth failures, etc.)
- Exponential backoff delays: 1s, 2s, 4s, 8s, 10s (capped at 10s)
Timeout Configuration:
- Default timeout: 30 seconds per request
- Applies to all API requests (translate, usage, languages, etc.)
Features:
- β Automatic retry on transient failures
- β Exponential backoff to avoid overwhelming the API
- β Smart error detection (retries 5xx, not 4xx)
- β Configurable timeout and retry limits (programmatic API only)
- β Works across all DeepL API endpoints
Retry Behavior Examples:
# Network failure - automatically retries up to 3 times deepl translate "Hello" --to es # If API returns 503 (service unavailable), retries automatically # Authentication failure (403) - does not retry deepl translate "Hello" --to es # Fails immediately without retries on auth errors # Rate limiting (429) - does not retry # You may want to wait before retrying manually
Note: Retry and timeout settings use sensible defaults optimized for the DeepL API. These are internal features that work automatically - no configuration required.
Glossaries
DeepL glossaries ensure consistent terminology across translations. The v3 Glossary API supports both single-target and multilingual glossaries (one glossary with multiple target languages).
# Create a single-target glossary from TSV file # File format: source_term<TAB>target_term per line echo -e "API\tAPI\nREST\tREST\nauthentication\tAuthentifizierung" > glossary.tsv deepl glossary create tech-terms en de glossary.tsv # β Glossary created: tech-terms (ID: abc123...) # Source language: EN # Target languages: DE # Type: Single target # Total entries: 3 # List all glossaries deepl glossary list # π tech-terms (enβde) - 3 entries # π multilingual-terms (enβ3 targets) - 15 entries # Show glossary details deepl glossary show tech-terms # Name: tech-terms # ID: abc123... # Source language: en # Target languages: de # Type: Single target # Total entries: 3 # Created: 2024-10-07T12:34:56Z # Show glossary entries (single-target glossary - no --target flag needed) deepl glossary entries tech-terms # API β API # REST β REST # authentication β Authentifizierung # Show entries for multilingual glossary (--target flag required) deepl glossary entries multilingual-terms --target-lang es # API β API # cache β cachΓ© # ... # Delete glossary deepl glossary delete tech-terms # β Glossary deleted: tech-terms # Preview what would be deleted without performing the operation deepl glossary delete tech-terms --dry-run # List supported glossary language pairs deepl glossary languages # de β en # de β fr # de β it # en β de # en β es # en β fr # en β ja # en β pt # ... # Add a new entry to an existing glossary deepl glossary add-entry tech-terms "database" "Datenbank" # β Entry added successfully # Add entry to multilingual glossary (requires --target-lang flag) deepl glossary add-entry multilingual-terms "cache" "cachΓ©" --target-lang es # Update an existing entry in a glossary deepl glossary update-entry tech-terms "API" "API (Programmierschnittstelle)" # β Entry updated successfully # Remove an entry from a glossary deepl glossary remove-entry tech-terms "REST" # β Entry removed successfully # Rename a glossary deepl glossary rename tech-terms "Technical Terms v2" # β Glossary renamed successfully # Update glossary name and/or dictionary entries in a single request deepl glossary update my-terms --name "Updated Terms" --target-lang de --file updated.tsv # Replace all entries in a glossary dictionary from a new file (v3 API only) # Unlike individual entry updates (which merge), this replaces the entire dictionary deepl glossary replace-dictionary multilingual-terms es updated-entries.tsv # β Dictionary replaced successfully (es) # Note: All existing entries for the target language are removed and replaced # The file format is the same as for 'glossary create' (TSV or CSV) # Delete a dictionary from a multilingual glossary (v3 API only) # Removes a specific language pair from a multilingual glossary deepl glossary delete-dictionary multilingual-terms es # β Dictionary deleted successfully (es) # Note: This only works with multilingual glossaries (multiple target languages) # For single-target glossaries, use 'glossary delete' to remove the entire glossary
Glossary file format (TSV):
source_term target_term API API REST REST authentication Authentifizierung
Key Features:
- Single-target glossaries - One source language β one target language (e.g., EN β DE)
- Multilingual glossaries - One source language β multiple target languages (e.g., EN β ES, FR, DE)
- Direct updates - v3 API uses PATCH endpoints for efficient updates (no delete+recreate)
- Smart defaults -
--targetflag only required for multilingual glossaries - Visual indicators - π for single-target, π for multilingual glossaries
- Translation integration - Use
--glossaryflag in translate and watch commands to apply glossary terms
Style Rules
Style rules are pre-configured translation rules created via the DeepL web UI and applied to translations using their ID (Pro API only).
# List available style rules deepl style-rules list # List with detailed information deepl style-rules list --detailed # JSON output deepl style-rules list --format json # Paginate results deepl style-rules list --page 2 --page-size 10 # Apply a style rule to a translation deepl translate "Hello" --to de --style-id "abc-123-def-456"
Admin API
Manage API keys and view organization usage analytics (requires admin-level API key).
# List all API keys in the organization deepl admin keys list # List keys in JSON format deepl admin keys list --format json # Create a new API key deepl admin keys create --label "Production Key" # Rename an API key deepl admin keys rename <key-id> "New Label" # Set character usage limit deepl admin keys set-limit <key-id> 1000000 # Remove usage limit (unlimited) deepl admin keys set-limit <key-id> unlimited # Deactivate an API key (permanent, cannot be undone) deepl admin keys deactivate <key-id> # Deactivate without confirmation prompt deepl admin keys deactivate <key-id> --yes # View organization usage for a date range (includes per-product breakdown) deepl admin usage --start 2024-01-01 --end 2024-12-31 # Period: 2024-01-01 to 2024-12-31 # # Total Usage: # Total: 10,000 # Translation: 7,000 # Documents: 2,000 # Write: 1,000 # Usage grouped by key (shows per-product breakdown per key) deepl admin usage --start 2024-01-01 --end 2024-12-31 --group-by key # Daily usage per key deepl admin usage --start 2024-01-01 --end 2024-01-31 --group-by key_and_day # JSON output for programmatic use deepl admin usage --start 2024-01-01 --end 2024-12-31 --format json
Key Management:
- list - View all API keys in the organization
- create - Create a new key with an optional label
- rename - Change the label of an existing key
- set-limit - Set or remove character usage limits
- deactivate - Permanently deactivate a key (requires confirmation)
Usage Analytics:
- Per-product character breakdowns (translation, documents, write)
- Group by key or by key and day for cost allocation
- JSON output for integration with monitoring tools
Note: Admin API endpoints require an admin-level API key, not a regular developer key. Key deactivation is permanent and cannot be undone.
Shell Completion
Generate shell completion scripts for tab-completion of commands, options, and arguments:
# Bash deepl completion bash > /etc/bash_completion.d/deepl # Zsh deepl completion zsh > "${fpath[1]}/_deepl" # Fish deepl completion fish > ~/.config/fish/completions/deepl.fish # Or source directly in your current session source <(deepl completion bash)
Cache Management
The CLI uses a local SQLite database to cache translations and write improvements, reducing API calls.
# View cache statistics deepl cache stats # Cache Status: enabled # Entries: 42 # Size: 1.23 MB / 1024.00 MB (0.1% used) # Clear all cached translations deepl cache clear # β Cache cleared successfully # Preview what would be cleared without performing the operation deepl cache clear --dry-run # Enable caching deepl cache enable # β Cache enabled # Disable caching deepl cache disable # β Cache disabled
Cache location: ~/.cache/deepl-cli/cache.db (or ~/.deepl-cli/cache.db for legacy installations)
π» Development
Prerequisites
- Node.js >= 20.0.0
- npm >= 9.0.0
- DeepL API key
Setup
# Clone repository git clone https://github.com/DeepLcom/deepl-cli.git cd deepl-cli # Install dependencies npm install # Run tests npm test # Run tests in watch mode npm test -- --watch # Run tests with coverage npm run test:coverage # Lint code npm run lint # Type check npm run type-check # Build npm run build
Development Workflow
See CLAUDE.md for comprehensive development guidelines.
Project Structure
deepl-cli/
βββ src/
β βββ cli/ # CLI interface and commands
β βββ services/ # Business logic
β βββ api/ # DeepL API client
β βββ storage/ # Data persistence (cache, config)
β βββ utils/ # Utility functions
β βββ types/ # Type definitions
βββ tests/
β βββ unit/ # Unit tests
β βββ integration/ # Integration tests
β βββ e2e/ # End-to-end tests
βββ docs/ # Documentation
βββ examples/ # Usage examples
βββ CLAUDE.md # Development guidelines
βββ README.md # This file
Running Locally
# Run CLI without building npm run dev -- translate "Hello" --to es # Or link for global usage npm link deepl translate "Hello" --to es
ποΈ Architecture
DeepL CLI follows a layered architecture:
CLI Interface (Commands, Parsing, Help)
β
Core Application (Command Handlers, Interactive Shell)
β
Service Layer (Translation, Write, Cache, Watch, Glossary)
β
API Client (DeepL Translate, Write, Glossary APIs)
β
Storage (SQLite Cache, Config, Translation Memory)
Key Components
- Translation Service - Core translation logic with caching and preservation
- Write Service - Grammar and style enhancement
- Cache Service - SQLite-based cache with LRU eviction
- Preservation Service - Preserves code blocks, variables, formatting
- Watch Service - File watching with debouncing
- Glossary Service - Glossary management and application
π§ͺ Testing
# Run all tests npm test # Run specific test type npm run test:unit npm run test:integration npm run test:e2e # Run specific test file npm test -- translation.test.ts # Run with coverage report npm run test:coverage # Watch mode for TDD npm test -- --watch # Run all example scripts (validation) npm run examples # Run example scripts (fast mode, skips slow examples) npm run examples:fast
π Documentation
- API Reference - Complete API reference with all commands, flags, and options
- Troubleshooting - Common issues, solutions, and exit codes reference
- Examples - Practical usage examples for every feature
- Changelog - Release history and version notes
- Development Guidelines - TDD workflow and contribution standards
- DeepL API Docs - Official API documentation
- CLI Guidelines - Command-line best practices
π Environment Variables
| Variable | Description |
|---|---|
DEEPL_API_KEY |
API authentication key |
DEEPL_CONFIG_DIR |
Override config and cache directory |
XDG_CONFIG_HOME |
Override XDG config base (default: ~/.config) |
XDG_CACHE_HOME |
Override XDG cache base (default: ~/.cache) |
NO_COLOR |
Disable colored output |
FORCE_COLOR |
Force colored output even when terminal doesn't support it. Useful in CI. NO_COLOR takes priority if both are set. |
TERM=dumb |
Disables colored output and progress spinners. Automatically set by some CI environments and editors. |
See docs/API.md#environment-variables for full details.
π Security & Privacy
- API key storage - Keys are stored as plaintext in
config.jsonwith0600file permissions (owner read/write only). For CI/CD or shared environments, prefer theDEEPL_API_KEYenvironment variable instead. Avoid committingconfig.jsonto version control β it is gitignored by default. - Local caching - All cached data stored locally in SQLite, never shared
- No telemetry - Zero usage tracking or data collection
- Environment variable support - Use
DEEPL_API_KEYenvironment variable for CI/CD - GDPR compliant - Follows DeepL's GDPR compliance guidelines
π License
This project is licensed under the MIT License - see the LICENSE file for details.
Powered by DeepL's next-generation language model