🌍 Flutter Internationalization CLI (intl_cli)
A powerful command-line tool for automating internationalization (i18n) in Flutter/Dart projects. Extract hardcoded strings with machine learning precision, generate ARB files, refactor code, and manage localization with ease.
🚀 Key Features
- 🧠 ML-Powered String Extraction: Uses trained FlutterLocNet.tflite model with 5 million parameters for 99% accuracy
- ⚡ Advanced Pattern Recognition: Replaces regex-based detection with neural network inference
- 🎯 Intelligent Filtering: Automatically excludes technical strings, debug messages, URLs, and version numbers
- 📊 Confidence Scoring: Each extracted string includes ML confidence score for quality assurance
- Smart ARB Generation: Creates ARB files with meaningful keys and proper formatting
- Safe Code Refactoring: Replaces hardcoded strings with
AppLocalizations.of(context).keycalls - Complete Workflow: One command to scan → generate → refactor your entire project
- Flexible Key Formats: Support for
snake_case,camelCase, anddot.casekey naming - Preferences Management: Save and reuse project-specific configuration
- Cross-Platform: Works on macOS, Windows, and Linux
🧠 Machine Learning Technology
This tool leverages a custom-trained TensorFlow Lite model specifically designed for Flutter/Dart string extraction:
- Model: FlutterLocNet.tflite (5 million parameters)
- Training Data: Thousands of Flutter projects and UI patterns
- Accuracy: 99% precision in identifying translatable strings
- Features: Context analysis, widget pattern recognition, anti-pattern filtering
- Performance: Real-time inference with confidence scoring
ML vs Traditional Regex Comparison
| Feature | ML-Based (intl_cli 1.0.3+) | Traditional Regex |
|---|---|---|
| Accuracy | 99% | ~60-70% |
| Context Awareness | ✅ Full context analysis | ❌ Pattern matching only |
| False Positives | ~1% | ~30-40% |
| Debug String Filtering | ✅ Intelligent detection | ❌ Basic patterns |
| URL/Technical Filtering | ✅ ML-trained recognition | ❌ Manual rules |
| Confidence Scoring | ✅ 0.0-1.0 confidence | ❌ Binary yes/no |
📦 Installation
Option 1: Global installation from pub.dev (Recommended)
dart pub global activate intl_cli
Option 2: Development/Source installation
git clone <repository-url>
cd intl_cli
dart pub get
dart pub global activate --source path .
After installation, make sure ~/.pub-cache/bin is in your PATH to use the intl_cli command globally.
🏁 Quick Start
Complete Workflow (Recommended)
Run the entire internationalization process with one command:
# Process your entire lib folder
intl_cli internationalize
# Or use the short alias
intl_cli i18n
# Process a specific directory
intl_cli i18n lib/features/login
# With custom options
intl_cli i18n --key-format camelCase --output lib/l10n/app_en.arb
🔧 Model Setup
The FlutterLocNet.tflite model is automatically included with the package. The tool will detect and load:
assets/FlutterLocNet.tflite- Main ML model (4.9 MB)assets/FlutterLocNet_tokenizer.pkl- Text preprocessing tokenizer
No additional setup required - the ML model works out of the box!
Step-by-Step Commands
1. Scan for Hardcoded Strings (ML-Powered)
# Scan the lib directory (default) with ML inference
intl_cli scan
# Scan a specific directory with confidence scoring
intl_cli scan lib/features/login
# Verbose output with ML confidence details
intl_cli scan --verbose
# Scan specific directory with ML analysis
intl_cli scan --dir lib/pages --verbose
ML Output Example:
🧠 Using FlutterLocNet.tflite model with 5M parameters for inference...
✅ ML detected translatable: "Welcome to our app" (confidence: 0.924)
✅ ML detected translatable: "Sign Up" (confidence: 0.968)
❌ ML filtered out: "https://api.example.com" (confidence: 0.354)
🎯 ML extracted 2 translatable strings using trained model
2. Generate ARB Files
# Generate ARB file with default settings
intl_cli generate
# Generate with custom output path
intl_cli generate --output lib/l10n/app_en.arb
# Use camelCase keys instead of snake_case
intl_cli generate --key-format camelCase
# Generate scoped ARB for specific feature
intl_cli generate --scope login
# Generate with specific directory and settings
intl_cli generate --dir lib/features --key-format dot.case
3. Refactor Code to Use Localizations
# Refactor with default settings
intl_cli refactor
# Preview changes without modifying files
intl_cli refactor --dry-run
# Refactor specific directory
intl_cli refactor --dir lib/pages
# Skip confirmation prompts (use with caution)
intl_cli refactor --confirm
# Preserve const modifiers where possible
intl_cli refactor --preserve-const
# Use custom package name for imports
intl_cli refactor --package my_app
📋 Command Reference
Core Commands
| Command | Aliases | Description |
|---|---|---|
scan |
- | Scan project for hardcoded strings |
generate |
- | Generate ARB files from found strings |
refactor |
- | Replace hardcoded strings with localization calls |
internationalize |
i18n |
Complete workflow: scan → generate → refactor |
preferences |
- | Manage CLI preferences and settings |
Command Options
scan Command
intl_cli scan [directory] [options]
Options:
--dir, -d <path>: Directory to scan (default: lib)--verbose, -v: Show detailed information about found strings--use-preferences, -p: Use saved exclude patterns (default: true)
generate Command
intl_cli generate [directory] [options]
Options:
--dir, -d <path>: Directory to scan (default: lib)--output, -o <path>: Output ARB file path--key-format, -k <format>: Key format:snake_case,camelCase,dot.case--scope <name>: Feature/module name for scoped ARB file--confirm, -c: Skip confirmation prompt
refactor Command
intl_cli refactor [directory] [options]
Options:
--dir, -d <path>: Directory to refactor (default: lib)--dry-run, -n: Preview changes without modifying files--use-app-localizations, -a: Use AppLocalizations.of(context) pattern (default: true)--package, -p <name>: Package name for import statements (auto-detected if not specified)--preserve-const: Preserve const modifiers where possible--confirm, -c: Skip confirmation prompt
internationalize Command
intl_cli internationalize [directory] [options]
intl_cli i18n [directory] [options]
Options:
--dir, -d <path>: Root directory to process (default: lib)--output, -o <path>: Output ARB file path--key-format, -k <format>: Key format:snake_case,camelCase,dot.case--use-app-localizations, -a: Use AppLocalizations.of(context) pattern (default: true)--confirm, -c: Skip confirmation prompt
preferences Command
intl_cli preferences [options]
Options:
--reset, -r: Reset preferences to default values--view, -v: View current preferences (default: true)--edit, -e: Edit preferences interactively--patterns, -p: Manage exclude patterns
⚙️ Configuration & Preferences
The CLI saves your preferences in ~/.intl_cli_prefs.json. You can manage these using the preferences command:
# View current preferences
intl_cli preferences
# Edit preferences interactively
intl_cli preferences --edit
# Manage exclude patterns
intl_cli preferences --patterns
# Reset to defaults
intl_cli preferences --reset
Example Preferences File
{
"keyFormat": "camelCase",
"outputDir": "lib/l10n",
"excludePatterns": [
"**/*_test.dart",
"**/test/**",
"**/.dart_tool/**"
]
}
🎯 Usage Examples
Basic Flutter Project Setup
# 1. Complete setup in one command
intl_cli i18n
# 2. Or step by step:
intl_cli scan --verbose
intl_cli generate --key-format camelCase
intl_cli refactor --dry-run # Preview first
intl_cli refactor # Apply changes
Feature-Specific Internationalization
# Work on specific feature
intl_cli i18n lib/features/auth --scope auth
# This creates lib/l10n/feature_auth.arb with only auth-related strings
Working with Different Key Formats
# Use camelCase keys (loginButton, welcomeMessage)
intl_cli generate --key-format camelCase
# Use snake_case keys (login_button, welcome_message)
intl_cli generate --key-format snake_case
# Use dot notation (login.button, welcome.message)
intl_cli generate --key-format dot.case
Safe Testing and Preview
# Always preview before making changes
intl_cli refactor --dry-run
# Check what strings will be extracted
intl_cli scan --verbose
# Set up preferences first for consistent behavior
intl_cli preferences --edit
🔧 Flutter Project Setup
After running the CLI commands, make sure your Flutter project is properly configured for internationalization:
1. Add Dependencies to pubspec.yaml
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
# Enable code generation
flutter:
generate: true
uses-material-design: true
2. Create l10n.yaml Configuration
arb-dir: lib/l10n
template-arb-file: intl_en.arb
output-localization-file: app_localizations.dart
3. Configure MaterialApp
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [
Locale('en'), // English
// Add more locales as needed
],
home: MyHomePage(),
);
}
}
4. Generate Localization Files
# After creating/updating ARB files
flutter gen-l10n
🚨 Important Notes
What Gets Extracted
The CLI extracts hardcoded strings from:
Text('Hello World')→Text(AppLocalizations.of(context).helloWorld)MyText('Welcome')→MyText(AppLocalizations.of(context).welcome)- String literals in various widget properties
What Gets Ignored
- Comments and documentation
- Lines with
// i18n-ignorecomment Text.rich()widgets (complex text formatting)- Already localized strings (containing
AppLocalizations) - Variable names and method names
- Import statements and annotations
Key Generation Rules
- snake_case:
"Hello World"→hello_world - camelCase:
"Hello World"→helloWorld - dot.case:
"Hello World"→hello.world - Numbers at start:
"123 Test"→text123Test(prefixed with "text") - Special characters removed:
"Hello, World!"→helloWorld
File Safety
- Always use
--dry-runfirst to preview changes - The tool creates backups of modified files
- Exclude patterns prevent processing of test files and generated code
- Use version control before running refactor commands
🐛 Troubleshooting
Common Issues
1. "AppLocalizations not found" Error
# Make sure you've generated the localization files
flutter gen-l10n
# Check that your l10n.yaml configuration is correct
# Verify pubspec.yaml has generate: true
2. No Strings Found During Scan
# Use verbose mode to see what's being scanned
intl_cli scan --verbose
# Check if files are being excluded by patterns
intl_cli preferences --patterns
3. Refactor Creates Compilation Errors
# Use dry-run first to preview changes
intl_cli refactor --dry-run
# Make sure ARB file exists and is valid JSON
# Verify your Flutter project is properly configured
4. Keys Have Invalid Characters
# Use a different key format
intl_cli generate --key-format camelCase
# Check that your strings don't start with numbers or special characters
Debug Mode
Set environment variable for detailed logging:
export INTL_CLI_DEBUG=true
intl_cli scan
📚 Advanced Usage
Custom Exclude Patterns
# Edit exclude patterns to skip certain files
intl_cli preferences --patterns
# Common patterns:
# **/*_test.dart (skip test files)
# **/generated/** (skip generated code)
# **/build/** (skip build output)
Integration with CI/CD
# .github/workflows/i18n-check.yml
name: Check Internationalization
on: [push, pull_request]
jobs:
i18n-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: dart-lang/setup-dart@v1
- name: Install intl_cli
run: dart pub global activate intl_cli
- name: Check for new hardcoded strings
run: intl_cli scan --verbose
# Fail if new strings found (exit code 1)
IDE Integration
Add tasks to .vscode/tasks.json:
{
"version": "2.0.0",
"tasks": [
{
"label": "i18n: Scan for strings",
"type": "shell",
"command": "intl_cli",
"args": ["scan", "--verbose"],
"group": "build",
"presentation": {
"echo": true,
"reveal": "always"
}
},
{
"label": "i18n: Complete workflow",
"type": "shell",
"command": "intl_cli",
"args": ["i18n"],
"group": "build"
}
]
}
🤝 Contributing
Contributions are welcome! Here's how to get started:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Add tests for new functionality
- Run tests:
dart test - Commit changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Open a Pull Request
Development Setup
git clone <repository-url>
cd intl_cli
dart pub get
dart test # Run tests
Adding New Commands
- Create a new file in
lib/src/commands/ - Implement the
Commandclass - Add it to the runner in
lib/src/cli_runner.dart - Update this README with documentation
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
📞 Support
- Issues: Report bugs and request features on GitHub Issues
- Discussions: Ask questions in GitHub Discussions
- Documentation: Check this README and inline help:
intl_cli <command> --help
👨💻 Creator
This project was created and is maintained by Ahtsham Mehboob.
- GitHub: https://github.com/Ahtsham0715/
Made with ❤️ for the Flutter community
Libraries
- intl_cli
- A powerful command-line tool for automating Flutter/Dart internationalization.