linguaflow 0.1.0
linguaflow: ^0.1.0 copied to clipboard
AI-powered localization for Flutter apps. Runtime language switching, JSON translations, and automatic AI translation of missing keys.
π LinguaFlow #
AI-powered localization for Flutter apps.
Runtime language switching Β· JSON translations Β· Automatic AI translation of missing keys
Features #
| Feature | Status |
|---|---|
| Runtime language switching | β |
| JSON-based translations | β |
.tr(context) extension |
β |
| Persist selected language | β |
| AI translation of missing keys | β |
| Translation caching | β |
| CLI batch translation generator | β |
| Interactive provider setup wizard | β |
| OpenAI provider | β |
| Google Gemini provider | β |
| Anthropic Claude provider | β |
| NVIDIA NIM provider | β |
| DeepL provider | β |
| LibreTranslate provider (free) | β |
Installation #
dependencies:
linguaflow: ^0.1.0
Quick Setup #
1. Add your JSON translation files #
assets/
lang/
en.json
hi.json
fr.json
en.json
{
"welcome": "Welcome Back",
"hello": "Hello",
"settings": "Settings"
}
2. Declare assets in pubspec.yaml #
flutter:
assets:
- assets/lang/en.json
- assets/lang/hi.json
- assets/lang/fr.json
3. Configure your AI provider #
Run the interactive setup wizard once in your project:
dart run linguaflow:setup
It will ask you:
ββ Step 1 β Choose your AI provider
[1] OpenAI default: GPT-4.1-mini Best quality
[2] Google Gemini default: Gemini 2.0 Flash Fast & cheap
[3] Anthropic Claude default: Haiku 4.5 Balanced
[4] DeepL Translation-focused
[5] LibreTranslate Free & open source
Enter choice [1β5]: _
ββ Step 2 β Enter your API key
API key: _
β Saved to .linguaflow_config.json
β Added .linguaflow_config.json to .gitignore
4. Wrap your app #
import 'package:linguaflow/linguaflow.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Reads .linguaflow_config.json saved by `dart run linguaflow:setup`
final aiProvider =
await AiProviderFactory.fromConfig() ?? AiProviderFactory.fromEnv();
runApp(
LinguaFlowProvider(
config: const LocaleConfig(
fallbackLocale: 'en',
supportedLocales: ['en', 'hi', 'fr'],
),
aiProvider: aiProvider,
child: const MyApp(),
),
);
}
Usage #
Translate a string #
Text('welcome'.tr(context))
Switch language at runtime #
LinguaFlow.of(context).setLocale('hi');
The selected locale is persisted automatically β next app launch restores it.
AI translation for missing keys (async) #
FutureBuilder<String>(
future: 'new_key'.trAsync(context),
builder: (ctx, snap) => Text(snap.data ?? '...'),
)
Missing keys are automatically:
- Translated by AI
- Cached to disk
- Returned instantly on future calls
Configuring the AI Provider #
There are three ways to supply the API key β use whichever fits your workflow.
Option A β Interactive wizard (recommended for development) #
dart run linguaflow:setup
Saves a .linguaflow_config.json that is auto-loaded at runtime and
auto-added to .gitignore.
aiProvider: await AiProviderFactory.fromConfig()
Option B β --dart-define at build time (recommended for CI / production) #
No config file needed. The key is baked into the binary at compile time.
# OpenAI
flutter run --dart-define=OPENAI_API_KEY=sk-...
# Google Gemini
flutter run --dart-define=GEMINI_API_KEY=AIza...
# Anthropic Claude
flutter run --dart-define=ANTHROPIC_API_KEY=sk-ant-...
# NVIDIA NIM
flutter run --dart-define=NVIDIA_API_KEY=nvapi-...
# DeepL
flutter run --dart-define=DEEPL_API_KEY=your-key:fx
# LibreTranslate (public server β no key needed)
flutter run
aiProvider: AiProviderFactory.fromEnv()
Option C β Explicit provider (full control) #
// OpenAI
aiProvider: OpenAiProvider(apiKey: 'sk-...')
// Google Gemini
aiProvider: GeminiProvider(apiKey: 'AIza...', model: 'gemini-2.0-flash')
// Anthropic Claude
aiProvider: ClaudeProvider(apiKey: 'sk-ant-...', model: 'claude-haiku-4-5-20251001')
// NVIDIA NIM (LLaMA, Nemotron, Mixtral, and more)
aiProvider: NvidiaProvider(apiKey: 'nvapi-...')
aiProvider: NvidiaProvider(apiKey: 'nvapi-...', model: 'nvidia/llama-3.1-nemotron-70b-instruct')
// DeepL (free tier key ends with :fx)
aiProvider: DeepLProvider(apiKey: 'your-key:fx')
// LibreTranslate β free, no key required on public servers
aiProvider: LibreTranslateProvider()
// LibreTranslate β self-hosted
aiProvider: LibreTranslateProvider(endpoint: 'http://localhost:5000')
CLI β Batch Translation Generator #
Generate all translation files from your base JSON in one command:
dart run linguaflow:generate \
--key=sk-YOUR_OPENAI_KEY \
--source=assets/lang/en.json \
--targets=hi,fr,de,es,ja
Output:
[LinguaFlow] Loaded 12 keys from assets/lang/en.json
[LinguaFlow] Translating β Hindi...
[LinguaFlow] β Saved assets/lang/hi.json
[LinguaFlow] Translating β French...
[LinguaFlow] β Saved assets/lang/fr.json
[LinguaFlow] Done.
Architecture #
lib/
βββ linguaflow.dart β Public barrel export
βββ src/
βββ core/
β βββ locale_manager.dart β ChangeNotifier, orchestrates everything
β βββ translation_store.dart β In-memory translation map
β βββ cache_manager.dart β SharedPreferences AI cache
β βββ constants.dart
βββ models/
β βββ locale_config.dart β Config passed to LinguaFlowProvider
βββ services/
β βββ ai/
β β βββ ai_provider.dart β Abstract interface
β β βββ ai_provider_factory.dart β Factory: config / env / explicit
β β βββ openai_provider.dart
β β βββ gemini_provider.dart
β β βββ claude_provider.dart
β β βββ nvidia_provider.dart
β β βββ deepl_provider.dart
β β βββ libretranslate_provider.dart
β βββ file_loader.dart β Loads JSON from assets
β βββ storage_service.dart β Persists locale choice
βββ extensions/
β βββ string_extension.dart β .tr() / .trAsync()
βββ widgets/
β βββ linguaflow_provider.dart β Root widget + LinguaFlow accessor
βββ cli/
βββ setup.dart β dart run linguaflow:setup
βββ generate_translations.dart β dart run linguaflow:generate
Missing key resolution order #
.tr() called
β
βΌ
In-memory store ββfoundβββΆ return translation
β
not found
βΌ
Persistent cache ββfoundβββΆ warm store β return
β
not found
βΌ
AI provider ββsuccessβββΆ cache + store β return
β
fail / no provider
βΌ
Fallback locale ββfoundβββΆ return
β
not found
βΌ
Return raw key
Supported AI Providers #
| Provider | Class | Default model | API key |
|---|---|---|---|
| OpenAI | OpenAiProvider |
gpt-4.1-mini |
platform.openai.com |
| Google Gemini | GeminiProvider |
gemini-2.0-flash |
aistudio.google.com |
| Anthropic Claude | ClaudeProvider |
claude-haiku-4-5-20251001 |
console.anthropic.com |
| NVIDIA NIM | NvidiaProvider |
meta/llama-3.3-70b-instruct |
build.nvidia.com (free credits) |
| DeepL | DeepLProvider |
β | deepl.com/account |
| LibreTranslate | LibreTranslateProvider |
β | Free β no key needed |
Bring your own provider #
Extend AiProvider to plug in any translation backend:
class MyProvider extends AiProvider {
@override
Future<String> translate({
required String text,
required String targetLanguage,
}) async {
// call your API and return translated string
}
}
License #
MIT Β© Ambit Misra