arb_translator_gen_z 3.4.0
arb_translator_gen_z: ^3.4.0 copied to clipboard
Translate Flutter ARB files to 100+ languages. Free with Google Translate or use OpenAI, DeepL, Azure, or AWS. CLI + programmatic API, watch mode, and CI/CD support.
ARB Translator Gen Z 🌍 #
Translate Flutter .arb files to 100+ languages in one command.
Free via Google Translate — no API key needed. Or plug in OpenAI, DeepL, Azure, or AWS for higher quality. Works as a CLI tool or a Dart library.
# Install once
dart pub global activate arb_translator_gen_z
# Translate to French, Spanish, and German
arb_translator -s lib/l10n/app_en.arb -l fr es de
Contents #
- Features
- Installation
- Quick Start
- CLI Reference
- Configuration
- AI Providers
- Programmatic API
- Supported Languages
- CI/CD Integration
- Contributing
✨ Features #
| Feature | Description |
|---|---|
| Free translation | Google Translate — no API key, no account needed |
| AI providers | OpenAI · DeepL · Azure Translator · AWS Translate |
| 100+ languages | Full native-name support, RTL detection |
| Parallel processing | Up to 5× faster with concurrent batch requests |
| Translation memory | In-session caching cuts repeated API calls |
| Watch mode | Auto-translate whenever your source ARB changes |
| Interactive mode | Confirm each string before it's written |
| Diff preview | See what will change before applying |
| Validate-only | Check ARB format without translating (great for CI) |
| Custom output dir | Write translated files anywhere with -o |
| Retry & rate limiting | Exponential backoff and configurable delays |
| Full programmatic API | Use everything from Dart code |
🚀 Installation #
CLI (global) #
dart pub global activate arb_translator_gen_z
Make sure ~/.pub-cache/bin is in your PATH:
# zsh
echo 'export PATH="$PATH:$HOME/.pub-cache/bin"' >> ~/.zshrc && source ~/.zshrc
# bash
echo 'export PATH="$PATH:$HOME/.pub-cache/bin"' >> ~/.bashrc && source ~/.bashrc
Verify:
arb_translator --help
Library (project dependency) #
# pubspec.yaml
dependencies:
arb_translator_gen_z: ^3.3.0
dart pub get
🎮 Quick Start #
Translate to specific languages #
arb_translator -s lib/l10n/app_en.arb -l fr es de
Repeat -l or space-separate — both work:
arb_translator -s lib/l10n/app_en.arb -l fr -l es -l de
Translate to all 100+ languages #
arb_translator -s lib/l10n/app_en.arb -l all
Custom output directory #
arb_translator -s lib/l10n/app_en.arb -l fr es -o build/l10n
Use a specific AI provider #
# Requires OPENAI_API_KEY in your environment
arb_translator -s lib/l10n/app_en.arb -l fr --ai-provider openai
Preview changes before writing #
arb_translator -s lib/l10n/app_en.arb -l fr --diff
Auto-translate on file changes (watch mode) #
arb_translator -s lib/l10n/app_en.arb -l fr es --watch
Validate only (no translation) #
arb_translator -s lib/l10n/app_en.arb --validate-only
📋 CLI Reference #
Options #
| Option | Short | Description | Default |
|---|---|---|---|
--source |
-s |
Source ARB file path | — |
--languages |
-l |
Target language codes (repeat or space-separate, or all) |
— |
--output-dir |
-o |
Directory for translated files (defaults to source dir) | — |
--ai-provider |
AI provider: google openai deepl azure aws |
google |
|
--config |
-c |
Path to YAML config file | ~/.arb_translator/config.yaml |
--overwrite |
Overwrite existing translations | true |
|
--verbose |
-v |
Debug-level logging | false |
--quiet |
-q |
Suppress non-error output | false |
Commands / flags #
| Flag | Description |
|---|---|
--help -h |
Show help |
--init-config |
Create starter config file at ~/.arb_translator/config.yaml |
--list-languages |
List all 100+ supported languages |
--popular |
Show the most-used language codes |
--validate-only |
Validate ARB file structure without translating |
--diff |
Preview changes without writing files |
--interactive |
Confirm each string before translating |
--watch |
Watch source file and re-translate on changes |
--stats |
Show translation statistics and cache info |
--test-ai-providers |
Health-check all configured AI providers |
--ai-stats |
Show AI provider details and availability |
--clean-cache |
Clear the translation memory cache |
Examples #
# 1. Translate to European languages
arb_translator -s lib/l10n/app_en.arb -l fr es de it pt nl
# 2. Translate to Asian languages
arb_translator -s lib/l10n/app_en.arb -l ja ko zh zh-TW
# 3. All languages, custom output dir
arb_translator -s lib/l10n/app_en.arb -l all -o build/l10n
# 4. OpenAI for highest quality
arb_translator -s lib/l10n/app_en.arb -l fr de --ai-provider openai
# 5. DeepL for European languages
arb_translator -s lib/l10n/app_en.arb -l fr de es --ai-provider deepl
# 6. CI: validate then translate quietly
arb_translator -s lib/l10n/app_en.arb --validate-only --quiet
arb_translator -s lib/l10n/app_en.arb -l fr es de --quiet
# 7. Interactive — confirm each string
arb_translator -s lib/l10n/app_en.arb -l fr --interactive
# 8. Watch during development
arb_translator -s lib/l10n/app_en.arb -l fr es --watch
# 9. Check translation stats and cache usage
arb_translator --stats -s lib/l10n/app_en.arb
# 10. Test all configured AI providers
arb_translator --test-ai-providers
⚙️ Configuration #
Generate a starter config file:
arb_translator --init-config
This creates ~/.arb_translator/config.yaml:
# Maximum parallel translation requests (higher = faster, but more API load)
maxConcurrentTranslations: 5
# Retry behaviour
retryAttempts: 3
retryDelayMs: 1000
requestTimeoutMs: 30000
# Rate limiting between requests (ms)
rateLimitDelayMs: 100
# Source language ("auto" detects from @@locale)
sourceLanguage: "auto"
# Output formatting
prettyPrintJson: true
backupOriginal: false
validateOutput: true
# Logging: debug | info | warning | error
logLevel: "info"
You can also pass a config file explicitly:
arb_translator -s lib/l10n/app_en.arb -l fr -c ci_config.yaml
🤖 AI Providers #
By default, the tool uses Google Translate (free, no key required). For higher quality or specialised languages, configure an AI provider.
Provider comparison #
| Provider | Quality | Cost | Setup |
|---|---|---|---|
| Google Translate | ⭐⭐⭐ | Free | Nothing — works out of the box |
| OpenAI GPT-4 | ⭐⭐⭐⭐⭐ | $$$ | OPENAI_API_KEY |
| DeepL | ⭐⭐⭐⭐⭐ | $$ | DEEPL_API_KEY |
| Azure Translator | ⭐⭐⭐⭐ | $$ | AZURE_TRANSLATOR_KEY + region |
| AWS Translate | ⭐⭐⭐ | $$ | AWS_TRANSLATE_ACCESS_KEY + secret + region |
Set up an AI provider #
Via environment variables (recommended):
export OPENAI_API_KEY="sk-..."
arb_translator -s lib/l10n/app_en.arb -l fr --ai-provider openai
Via config file:
# ~/.arb_translator/config.yaml
aiModel:
preferredProvider: "openai" # google | openai | deepl | azure | aws
qualityThreshold: 0.8
enableAutoCorrection: false
maxTokensPerRequest: 4000
openaiApiKey: "${OPENAI_API_KEY}"
deeplApiKey: "${DEEPL_API_KEY}"
azureTranslatorKey: "${AZURE_TRANSLATOR_KEY}"
azureTranslatorRegion: "eastus"
awsTranslateAccessKey: "${AWS_ACCESS_KEY_ID}"
awsTranslateSecretKey: "${AWS_SECRET_ACCESS_KEY}"
awsTranslateRegion: "us-east-1"
Test provider health #
arb_translator --test-ai-providers
🔧 Programmatic API #
Basic usage #
import 'package:arb_translator_gen_z/arb_translator_gen_z.dart';
Future<void> main() async {
const config = TranslatorConfig();
final translator = LocalizationTranslator(config);
try {
// Single language
final path = await translator.generateForLanguage(
'lib/l10n/app_en.arb',
'fr',
);
print('Written to: $path');
// Multiple languages
final results = await translator.generateMultipleLanguages(
'lib/l10n/app_en.arb',
['es', 'de', 'it', 'pt', 'ja'],
);
for (final entry in results.entries) {
print('${entry.key}: ${entry.value}');
}
} finally {
translator.dispose();
}
}
Custom configuration #
const config = TranslatorConfig(
maxConcurrentTranslations: 10, // parallelism
retryAttempts: 5,
logLevel: LogLevel.warning, // quieter for CI
rateLimitDelayMs: 200,
);
AI provider configuration #
import 'dart:io';
import 'package:arb_translator_gen_z/arb_translator_gen_z.dart';
final config = TranslatorConfig(
aiModelConfig: AIModelConfig(
openaiApiKey: Platform.environment['OPENAI_API_KEY'],
preferredProvider: TranslationProvider.openai,
enableAutoCorrection: true,
),
);
final translator = LocalizationTranslator(config);
final path = await translator.generateForLanguage('lib/l10n/app_en.arb', 'fr');
translator.dispose();
Custom output directory #
final path = await translator.generateForLanguage(
'lib/l10n/app_en.arb',
'fr',
outputDir: 'build/l10n',
);
ARB file utilities #
import 'package:arb_translator_gen_z/arb_translator_gen_z.dart';
// Read and validate
final content = await ArbHelper.readArbFile('lib/l10n/app_en.arb');
final issues = ArbHelper.validateArbContent(content);
if (issues.isNotEmpty) {
print('Validation issues: $issues');
}
// Extract translations vs metadata
final translations = ArbHelper.getTranslations(content);
final metadata = ArbHelper.getMetadata(content);
Language utilities #
// Get language info
final info = getLanguageInfo('fr');
print('${info?.name}: ${info?.nativeName}'); // French: Français
// Validate a code (returns normalised code or null)
final code = validateLangCode('FR'); // returns 'fr'
// Typo suggestions
final suggestions = suggestLanguageCodes('fren'); // ['fr']
// List all codes
print(supportedLangCodes.length); // 100+
Translation service (direct) #
final service = TranslationService(config);
try {
// Single string
final translated = await service.translateText('Hello', 'es', sourceLang: 'en');
print(translated); // Hola
// Batch strings
final batch = await service.translateBatch(
{'greeting': 'Hello', 'farewell': 'Goodbye'},
'es',
);
print(batch); // {greeting: Hola, farewell: Adiós}
// Cost estimates across providers
final costs = service.getCostEstimates('Hello, world!');
// Provider health check
final health = await service.testAIProviders();
} finally {
await service.dispose();
}
Error handling #
try {
await translator.generateForLanguage('app_en.arb', 'fr');
} on ArbFileNotFoundException catch (e) {
print('File not found: ${e.filePath}');
} on ArbFileFormatException catch (e) {
print('Bad ARB format in ${e.filePath}: ${e.details}');
} on UnsupportedLanguageException catch (e) {
final hints = suggestLanguageCodes(e.languageCode);
print('Unknown language "${e.languageCode}". Try: $hints');
} on TranslationApiException catch (e) {
print('API error ${e.statusCode}: ${e.details}');
}
🌐 Supported Languages #
100+ languages with native names. Quick reference:
af Afrikaans ar العربية bg Български bn বাংলা
ca Català cs Čeština cy Cymraeg da Dansk
de Deutsch el Ελληνικά en English es Español
et Eesti fa فارسی fi Suomi fr Français
gu ગુજરાતી he עברית hi हिन्दी hr Hrvatski
hu Magyar hy Հայերեն id Indonesia is Íslenska
it Italiano ja 日本語 ka ქართული kn ಕನ್ನಡ
ko 한국어 lt Lietuvių lv Latviešu mk Македонски
ml മലയാളം mr मराठी ms Melayu mt Malti
nl Nederlands no Norsk pa ਪੰਜਾਬੀ pl Polski
pt Português ro Română ru Русский sk Slovenčina
sl Slovenščina sq Shqip sr Српски sv Svenska
sw Kiswahili ta தமிழ் te తెలుగు th ภาษาไทย
tl Filipino tr Türkçe uk Українська ur اردو
vi Tiếng Việt zh 中文(简体) zh-TW 中文(繁體)
# See all languages
arb_translator --list-languages
# Show popular codes only
arb_translator --popular
🏗️ CI/CD Integration #
GitHub Actions #
# .github/workflows/translate.yml
name: Translate ARB Files
on:
push:
paths:
- 'lib/l10n/app_en.arb'
jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dart-lang/setup-dart@v1
- name: Install ARB Translator
run: dart pub global activate arb_translator_gen_z
- name: Validate source file
run: arb_translator -s lib/l10n/app_en.arb --validate-only
- name: Translate
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: |
arb_translator \
-s lib/l10n/app_en.arb \
-l fr es de it pt ja ko zh \
--ai-provider openai \
--quiet
- name: Commit translations
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add lib/l10n/
git diff --cached --quiet || git commit -m "chore: update translations"
git push
Dart code in CI #
import 'dart:io';
import 'package:arb_translator_gen_z/arb_translator_gen_z.dart';
Future<void> main() async {
const config = TranslatorConfig(logLevel: LogLevel.warning);
final translator = LocalizationTranslator(config);
try {
// Validate first — exits non-zero if invalid
final content = await ArbHelper.readArbFile('lib/l10n/app_en.arb');
final issues = ArbHelper.validateArbContent(content);
if (issues.isNotEmpty) {
stderr.writeln('Validation failed:\n${issues.join('\n')}');
exit(1);
}
// Translate required languages
final langs = Platform.environment['REQUIRED_LANGUAGES']?.split(',')
?? ['fr', 'es', 'de'];
final results = await translator.generateMultipleLanguages(
'lib/l10n/app_en.arb',
langs,
);
final failed = results.entries.where((e) => e.value.isEmpty).toList();
if (failed.isNotEmpty) {
stderr.writeln('Failed: ${failed.map((e) => e.key).join(', ')}');
exit(1);
}
print('All translations generated.');
} finally {
translator.dispose();
}
}
📁 ARB File Format #
A valid ARB file looks like this:
{
"@@locale": "en",
"appTitle": "My App",
"@appTitle": {
"description": "The application title shown in the header"
},
"greeting": "Hello, {name}!",
"@greeting": {
"description": "Personalized greeting",
"placeholders": {
"name": { "type": "String" }
}
},
"itemCount": "{count, plural, one{1 item} other{{count} items}}",
"@itemCount": {
"description": "Item count with pluralization",
"placeholders": {
"count": { "type": "int" }
}
}
}
The translator preserves all @ metadata and copies placeholders unchanged.
📈 Performance #
With default settings (maxConcurrentTranslations: 5):
| Strings | 1 language | 10 languages | All languages (100+) |
|---|---|---|---|
| 10 | ~1s | ~5s | ~2 min |
| 50 | ~3s | ~20s | ~8 min |
| 200 | ~10s | ~1 min | ~30 min |
Increase maxConcurrentTranslations for faster results (watch rate limits):
# In config.yaml
maxConcurrentTranslations: 10
Translation memory avoids re-translating identical strings across runs in the same session.
🛠️ Development #
git clone https://github.com/sauravkhanalgit/arb_translator.git
cd arb_translator
dart pub get
# Run tests
dart test
# Static analysis (should be clean)
dart analyze
# Run the CLI locally
dart run bin/arb_translator.dart --help
🤝 Contributing #
- Fork the repo
- Create a branch:
git checkout -b feature/my-feature - Make your changes and add tests
- Run
dart test && dart analyze - Open a pull request
Please open an issue first for significant changes.
📄 License #
MIT — see LICENSE.
Made with ❤️ for the Flutter community.
Star ⭐ the repo if it saves you time!