
FlutterAndroidBuild SystemDevelopment
How I Made My Flutter App Modular with Multiple Flavors
6 min read
How I Made My Flutter App Modular with Multiple Flavors
In this post, I'll share how I structured a modular Flutter app with multiple build flavors—one of which required unique Android permissions and behavior. Managing configurations across environments while avoiding code duplication was a fun challenge.
Why Flavors?
We needed to support:
- A consumer-facing app (no advanced permissions)
- An internal tester/debug app (with elevated permissions)
Rather than clone the app or manually swap configs, flavors gave us clean separation and automation.
Flavor Setup
- Defined flavors in
build.gradle
:
CopyproductFlavors { consumer { dimension "app" applicationIdSuffix ".consumer" } internal { dimension "app" applicationIdSuffix ".internal" } }
- Used different
AndroidManifest.xml
files:
src/
├── consumer/
│ └── AndroidManifest.xml
├── internal/
│ └── AndroidManifest.xml
- Flutter flavor entry points:
Copyflutter run --flavor consumer -t lib/main_consumer.dart flutter run --flavor internal -t lib/main_internal.dart
Challenges
- Ensuring all shared code was kept outside flavor-specific files
- Avoiding duplication across manifests and Gradle configs
Tips
- Use conditional imports for flavor-specific logic
- Externalize secrets per flavor
- Automate build matrix via CI
Outcome
- Clean, maintainable codebase
- Fast switching between environments
- Fewer config bugs in production