A CLI tool for automatically translating JSON language files using DeepL and Claude (Anthropic). Designed for projects with many target languages where you need both high translation quality and an efficient workflow.
Managing translations in Laravel projects (and similar frameworks) with dozens of languages is painful. The existing options each have trade-offs:
- POEdit + DeepL delivers excellent translation quality, but the manual workflow becomes cumbersome when you have dozens of languages and hundreds of keys. Every new key means clicking through each language file one by one.
- Automated LLM-based packages are easy to integrate, but the translation quality is often mediocre -- they miss context, mangle placeholders, and produce inconsistent results.
autotrans was built to get the best of both worlds: the translation quality of DeepL combined with the automation and intelligence of Claude AI. It uses DeepL as the primary translation engine for its 100+ supported languages, falls back to Claude for unsupported languages, and uses Claude Sonnet to automatically detect and fix broken placeholders (like :name being translated to :naam).
- DeepL-first translation -- Uses DeepL for 100+ supported languages with high quality machine translation
- Claude AI fallback -- Automatically uses Claude Sonnet for languages not supported by DeepL
- Placeholder validation -- Detects and auto-fixes broken Laravel-style placeholders (
:name,:count, etc.) using Claude Sonnet - Translation memory -- Caches translations per language to avoid redundant API calls and reduce costs
- Smart batching -- Deduplicates identical source texts and chunks large batches (50 per API call)
- Rate limiting -- Separate rate-limited queues for translation (10 concurrent, 50/min) and validation (5 concurrent, 30/min)
- Per-key progress -- Granular progress bar tracking individual keys across all files
- Standalone validation -- Scan and fix existing translations without re-translating
# Clone the repository
git clone https://github.com/stevenbraham/autotrans.git
cd autotrans
# Install dependencies
npm install
# Build
npm run build
# Make the `autotrans` command available globally
npm linkCreate a .env file in the project root with your API keys:
DEEPL_API_KEY=your-deepl-api-key
ANTHROPIC_API_KEY=your-anthropic-api-key- DeepL API key: Get one at deepl.com/pro-api. Both free and pro plans are supported.
- Anthropic API key: Get one at console.anthropic.com. Required for placeholder validation and non-DeepL language translation.
autotrans expects a directory containing en.json (the source language) and one or more target language files:
lang/
en.json # Source (English)
de.json # German
fr.json # French
nl.json # Dutch
ja.json # Japanese
...
Each file is a flat JSON object with string keys and string values:
{
"welcome": "Welcome to :app_name",
"greeting": "Hello, :name!",
"items_count": "You have :count items"
}autotrans translate <dir>Scans all target language files, identifies missing keys (present in en.json but not in the target), and translates them. After translating, it also validates all existing translations for broken placeholders and fixes them.
# Translate all missing keys in the lang directory
autotrans translate ./resources/langWhat it does:
- Reads
en.jsonas the source - Checks translation memory for cached translations (zero API cost)
- Sends remaining texts to DeepL (or Claude for unsupported languages)
- Validates and fixes any broken placeholders via Claude Sonnet
- Saves translations and updates the memory cache
- Runs a final validation pass on all existing translations
autotrans validate <dir>Scans all existing translations for broken placeholders and fixes them using Claude Sonnet. This is useful for cleaning up translations that were done by other tools or manually.
# Validate and fix placeholders in all translated files
autotrans validate ./resources/langWhat it does:
- Reads
en.jsonto know which placeholders each key should have - Checks every translated key across all target files
- Identifies translations where placeholders are missing, translated, or malformed
- Batch-fixes broken translations via Claude Sonnet
- Reports how many were fixed
autotrans populate <dir> <langs>Creates empty JSON files for the specified languages. Useful when adding support for new languages.
# Create files for Spanish, Italian, and French
autotrans populate ./resources/lang es,it,frautotrans clean <dir>Resets all language files (except en.json) to empty objects {}. Requires interactive confirmation. Useful when you want to re-translate everything from scratch.
autotrans clean ./resources/lang1. Pre-scan Read en.json + all target files, compute missing keys
2. Memory lookup Check translation memory cache for each text
3. API translation Send remaining texts to DeepL or Claude (in chunks of 50)
4. Validation Check placeholders, batch-fix broken ones via Sonnet
5. Save Write updated files + save new entries to memory
6. Post-validate Run full placeholder validation on all existing keys
- DeepL-supported languages (100+): Translated via the DeepL API for optimal quality
- Unsupported languages: Translated via Claude Sonnet as a fallback
- Special mappings:
pt->pt-PT,en->en-US,no->nb(DeepL requirements)
autotrans understands Laravel-style placeholders (:name, :count, :app_name, etc.) and ensures they are never translated or mangled. When a translation contains broken placeholders, Claude Sonnet is used to fix the translation while preserving the correct placeholder syntax.
Translations are cached per language in ~/.autotrans/memory/. When the same English text appears again (in any file), the cached translation is used instead of making an API call. This significantly reduces costs when adding new keys across many languages.
# Run in development mode (no build step)
npm run dev -- translate ./resources/lang
# Run tests with coverage
npm test
# Build for production
npm run buildnpm testTests use Jest with ts-jest. Coverage thresholds are enforced for core modules. Test fixtures use OS temp directories and are cleaned up automatically.
MIT