About flutter-config
A Flutter configuration skill for organizing dev, staging, and prod flavors around one main.dart entry point. It describes centralized configuration, platform flavor setup, Firebase separation, and secret-handling rules.
Key features
- 01Three-flavor setup with one entry point
- 02Per-flavor JSON configuration
- 03Centralized AppConfig values
- 04Android and iOS flavor setup
- 05Separate Firebase projects per flavor
- 06Secret-handling guidance
Use cases
- 01Running dev, staging, or prod builds
- 02Centralizing environment-specific settings
- 03Configuring platform flavors and Firebase
Install
Copy the command and run it in a terminal.
$
npx skills add https:/ / github.com/ dhruvanbhalara/ skills --skill flutter-configAfter installing, type/flutter-configin Claude Code to confirm it loaded.
Details
From the project READMEFlavor Architecture
- Define three flavors:
dev,staging,prod - Use a single
main.dartentry point for all flavors - Pass flavor-specific configuration via
--dart-define-from-file:flutter run --flavor dev --dart-define-from-file=config/dev.json flutter run --flavor staging --dart-define-from-file=config/staging.json flutter run --flavor prod --dart-define-from-file=config/prod.json - NEVER create separate
main_dev.dart,main_staging.dart,main_prod.dartentry points
Config JSON Structure
- Store per-flavor JSON config files in a
config/directory at project root:config/ ├── dev.json ├── staging.json └── prod.json - Example
config/dev.json:{ "FLAVOR": "dev", "BASE_URL": "https://api-dev.example.com", "APP_NAME": "MyApp Dev", "ENABLE_LOGGING": "true", "ENABLE_CRASHLYTICS": "false" } - NEVER put secrets (API keys, signing credentials) in these JSON files: use CI-injected env vars or
flutter_secure_storage - Add
config/*.jsonto.gitignoreif they contain any environment-specific secrets; otherwise commit them for team convenience
Entry Point Pattern
// lib/main.dart
void main() {
const flavor = String.fromEnvironment('FLAVOR', defaultValue: 'dev');
AppConfig.init(flavor: Flavor.fromString(flavor));
runApp(const App());
}
- Read all compile-time values via
String.fromEnvironment('KEY')orbool.fromEnvironment('KEY') - Use a sealed
Flavorenum:sealed class Flavor { dev, staging, prod } AppConfigis a singleton holding flavor, base URL, feature flags, and Firebase config
Environment Configuration
- Store per-flavor config in a centralized
AppConfigclass:baseUrl: API endpoint per environmentenableLogging: verbose logging for dev onlyenableCrashlytics: disabled in devappName: display name per flavor (e.g., "MyApp Dev", "MyApp")
- All values come from the JSON file via
--dart-define-from-file: NO hardcoded per-flavor logic in Dart code - NEVER put secrets in the JSON config files: use
flutter_secure_storageor CI-injected env vars
Platform-Specific Flavor Setup
Android
- Define
flavorDimensionsandproductFlavorsinandroid/app/build.gradle:flavorDimensions "environment" productFlavors { dev { dimension "environment"; applicationIdSuffix ".dev"; resValue "string", "app_name", "MyApp Dev" } staging { dimension "environment"; applicationIdSuffix ".staging"; resValue "string", "app_name", "MyApp Staging" } prod { dimension "environment"; resValue "string", "app_name", "MyApp" } }
iOS
- Create Xcode schemes for each flavor (Dev, Staging, Prod).
- Use xcconfig files for per-flavor bundle ID, display name, and signing.
- Map Flutter flavors to Xcode schemes in
ios/Runner.xcodeproj. - Swift Package Manager Integration: When configuring iOS flavors, Xcode schemes map package dependency configurations automatically. No CocoaPods
Podfilechanges are required for SPM. Ensure all dependency overrides are defined under Package Dependencies inside Xcode Runner project settings.
Firebase Per-Flavor
- Use separate Firebase projects per flavor (dev, staging, prod)
- Place
google-services.json(Android) andGoogleService-Info.plist(iOS) in flavor-specific directories - Use
flutterfire configurewith--projectflag for each environment
Build Commands
# Development
flutter run --flavor dev --dart-define-from-file=config/dev.json
# Staging
flutter run --flavor staging --dart-define-from-file=config/staging.json
# Production release
flutter build appbundle --flavor prod --dart-define-from-file=config/prod.json --release
flutter build ipa --flavor prod --dart-define-from-file=config/prod.json --release
Rules
- NEVER hardcode environment-specific values (URLs, API keys, feature flags)
- NEVER commit production secrets to the repository
- Every team member MUST be able to run any flavor locally with a single command
- CI/CD pipelines MUST specify both
--flavorand--dart-define-from-fileexplicitly - Use a single
main.dart: NEVER create separate entry points per flavor
Comments
Markdown supported