Skip to content

Flavorize Apps

Overview

We use flutter_flavorizr to manage different app environments (development, staging, production). This allows us to maintain separate configurations, API endpoints, and app identities for each environment.

Setup

1. Add Dependency

pubspec.yaml
dev_dependencies:
flutter_flavorizr: ^2.2.1

Configure flavors (minimum)

YAML

pubspec.yaml
flavorizr:
app:
android:
flavorDimensions: "env"
ios: {}
flavors:
dev:
app:
name: "MyApp Dev"
android:
applicationId: "com.company.myapp.dev"
ios:
bundleId: "com.company.myapp.dev"
staging:
app:
name: "MyApp Staging"
android:
applicationId: "com.company.myapp.staging"
ios:
bundleId: "com.company.myapp.staging"
prod:
app:
name: "MyApp"
android:
applicationId: "com.company.myapp"
ios:
bundleId: "com.company.myapp"

Generate native files

Bash

flutter pub run flutter_flavorizr

Rule: Re-run this command whenever flavor settings change (name/id/icons/firebase files).

3) Entry points

Create one entry file per flavor:

generated structure

lib/
main.dart
main_dev.dart
main_staging.dart
main_prod.dart
config/app_env.dart

dart

lib/main_dev.dart
import 'config/app_env.dart';
import 'main.dart' as app;
void main() {
AppEnv.init(Flavor.dev);
app.main();
}

dart

lib/main_prod.dart
import 'config/app_env.dart';
import 'main.dart' as app;
void main() {
AppEnv.init(Flavor.prod);
app.main();
}

4) Custom variables

Guideline: All environment-specific values must live in one place (AppEnv).
No hardcoded URLs/flags scattered across the codebase.

dart

lib/config/app_env.dart
enum Flavor { dev, staging, prod }
class AppEnv {
static late final Flavor flavor;
// Custom variables (examples)
static late final String apiBaseUrl;
static late final bool enableNetworkLogs;
static void init(Flavor f) {
flavor = f;
switch (f) {
case Flavor.dev:
apiBaseUrl = 'https://dev-api.company.com';
enableNetworkLogs = true;
break;
case Flavor.staging:
apiBaseUrl = 'https://staging-api.company.com';
enableNetworkLogs = true;
break;
case Flavor.prod:
apiBaseUrl = 'https://api.company.com';
enableNetworkLogs = false;
break;
}
}
static bool get isProd => flavor == Flavor.prod;
}

Run / Build commands (standard)

Bash

# Dev
flutter run --flavor dev -t lib/main_dev.dart
# Staging
flutter run --flavor staging -t lib/main_staging.dart
# Production
flutter run --flavor prod -t lib/main_prod.dart

Release builds:

Bash

flutter build apk --flavor prod -t lib/main_prod.dart
flutter build ipa --flavor prod -t lib/main_prod.dart

7) Rules

  • Always use --flavor <env> and the matching main_<env>.dart.
  • Never hardcode environment-specific values outside AppEnv.
  • prod must have logs off and must use production endpoints.
  • If using Firebase per environment, keep separate config files and map them per flavor via flavorizr (same pattern as bundle ids).