A type-safe, multi-flavor Flutter environment manager. Load Dev, Staging, and Production configuration from .env assets with startup validation and a singleton AppConfig API.
- Multi-flavor support —
AppEnv.dev,AppEnv.staging, andAppEnv.prodwith conventional asset paths. .envparsing — Comments, quoted values, whitespace trimming, and duplicate-key handling.- Startup validation — Fails fast when required keys are missing or empty.
- Type-safe access —
apiUrl,appName,enableLogging, and optional keys via typed getters. - Test-friendly —
initializeFromMapandresetForTestingfor unit tests without asset loading.
dependencies:
flutter_flavor_dotenv: ^0.0.1Place one file per flavor under assets/:
assets/
.env.dev
.env.staging
.env.prod
Example assets/.env.dev:
# Development environment
API_URL=https://api.dev.example.com
APP_NAME=MyApp (Dev)
ENABLE_LOGGING=true
BASE_URL=https://dev.example.comflutter:
assets:
- assets/.env.dev
- assets/.env.staging
- assets/.env.prod// lib/main_dev.dart
import 'package:flutter/material.dart';
import 'package:flutter_flavor_dotenv/flutter_flavor_dotenv.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await AppConfig.initialize(AppEnv.dev);
runApp(const MyApp());
}Repeat for main_staging.dart and main_prod.dart, passing AppEnv.staging and AppEnv.prod.
flutter run -t lib/main_dev.dart
flutter run -t lib/main_staging.dart
flutter run -t lib/main_prod.dart --releaseFor Android/iOS product flavors, see doc/android_flavor_setup.md.
final config = AppConfig.instance;
final apiUrl = config.apiUrl;
final appName = config.appName;
final logging = config.enableLogging;
final env = config.env; // AppEnv.dev
// Optional keys
final baseUrl = config.baseUrl;
final sentryDsn = config.sentryDsn;
final mapsApiKey = config.mapsApiKey;
// Arbitrary keys
final custom = config['CUSTOM_KEY'];await AppConfig.initialize(
AppEnv.prod,
requiredKeys: ['API_URL', 'APP_NAME', 'ENABLE_LOGGING', 'MAPS_API_KEY'],
);await AppConfig.initialize(
AppEnv.dev,
overrides: {'API_URL': 'https://localhost:8080'},
);AppConfig.initializeFromMap(AppEnv.dev, {
'API_URL': 'https://api.dev.example.com',
'APP_NAME': 'MyApp Dev',
'ENABLE_LOGGING': 'true',
});
// tearDown
AppConfig.resetForTesting();By default, every .env file must define:
| Key | Type | Description |
|---|---|---|
API_URL |
String |
API base URL |
APP_NAME |
String |
Human-readable app name |
ENABLE_LOGGING |
bool |
"true" or "false" (case-insensitive) |
| Key | Getter |
|---|---|
BASE_URL |
baseUrl |
SENTRY_DSN |
sentryDsn |
MAPS_API_KEY |
mapsApiKey |
Any other key is available via config['YOUR_KEY'].
See the example/ app for a working Dev/Staging/Prod setup with flavor entry points and sample .env files.
cd example
flutter run -t lib/main_dev.dart| Class | Purpose |
|---|---|
AppEnv |
Environment enum (dev, staging, prod) |
AppConfig |
Singleton config loaded at startup |
EnvLoader |
Load and parse .env asset files |
EnvValidator |
Validate required keys |
EnvValidationException |
Thrown when keys are missing |
EnvNotInitializedException |
Thrown when AppConfig.instance is used before init |
- License: Apache License 2.0 — see LICENSE.
- Changelog: CHANGELOG.md.
- Issues: GitHub Issues.
Contributions and bug reports are welcome via GitHub issues and pull requests.