Monorepo Toolkit
Flavor Manager
The flavor command manages app flavors (build variants) using flutter_flavorizr. It handles flavor configuration, native platform setup (Android product flavors, iOS schemes), IDE configurations, and entry point generation.

Subcommands
flavor list-apps
Lists all apps in the workspace that have flavor configurations:
dart run monorepo_toolkit flavor list-appsflavor list
Lists all configured flavors for a specific app:
dart run monorepo_toolkit flavor list --app template_appDisplays each flavor with its app name, Android application ID, and iOS bundle ID.
flavor add
Adds a new flavor to an app:
# Basic usage
dart run monorepo_toolkit flavor add --app template_app --name qa
# With custom app name suffix and bundle ID suffix
dart run monorepo_toolkit flavor add \
--app template_app \
--name qa \
--app-name "[QA]" \
--suffix ".qa"
# Add and immediately generate native files
dart run monorepo_toolkit flavor add --app template_app --name qa --generate| Flag | Description |
|---|---|
--app / -a | The app name (required) |
--name / -n | The flavor name, e.g., qa, uat, demo (required) |
--app-name | Custom app name suffix. Defaults to [FLAVOR_NAME] |
--suffix / -s | Bundle ID suffix. Defaults to .<flavor_name>. The iOS bundle ID drops underscores from it (.my_flavor becomes .myflavor), because Apple does not allow them |
--generate / -g | Run flutter_flavorizr after adding |
Flavor names must start with a lowercase letter and contain only lowercase letters, numbers, and underscores.
What one run changes:
dart run monorepo_toolkit flavor list --app template_appℹ Flavors for template_app:ℹ developmentℹ App name: Template App [Dev]ℹ Android ID: com.banuacoder.templateapp.devℹ iOS Bundle: com.banuacoder.templateapp.devℹ …ℹ productionℹ App name: Template App
flavors: # development, staging … production: app: name: "Template App" android: flavorDimension: "app" applicationId: "com.banuacoder.templateapp" icon: "launcher/logo.png" adaptiveIcon: background: "launcher/logo-background.png" foreground: "launcher/logo-foreground.png" ios: bundleId: "com.banuacoder.templateapp" icon: "launcher/ios-logo.png"instructions: # …{ "version": "0.2.0", "configurations": [ // development … { "name": "Template App - Production", "program": "${workspaceFolder}/apps/template_app/lib/main.dart", // … }, // staging … ]}flavor generate
Runs flutter_flavorizr to generate native platform files for all configured flavors:
dart run monorepo_toolkit flavor generate --app template_app
# Force regeneration even if inputs haven't changed
dart run monorepo_toolkit flavor generate --app template_app --force
# Check which flavors need regeneration without making changes
dart run monorepo_toolkit flavor generate --app template_app --checkThe generate command runs up to four steps:
flutter_flavorizrfor native Android/iOS flavor files and launcher icons- Native splash screen generation (if configured)
- IDE configuration generation (see IDE run configurations)
- Flavor-based
main_<flavor>.dartentry point files
Each step can be toggled with --no-splash, --no-icons, --no-ide-configs, or --no-main-files.
Step 4 creates only the missing entry files. Each one is a copy of lib/main.dart (or another main_<flavor>.dart) with the bootstrap(flavor: ...) argument changed, so it uses your real bootstrap and app widget. Existing files are not changed. For a new flavor, run env sync first so FlavorStatus has the new value.
flavor sync
Synchronizes flavor settings between the global flavors.yaml config and individual app configurations:
# Initialize global settings from existing app configs
dart run monorepo_toolkit flavor sync --init
# Sync global settings to all apps (add missing flavors)
dart run monorepo_toolkit flavor sync
# Sync a specific app only
dart run monorepo_toolkit flavor sync --app template_app
# Sync from app configs back to global settings
dart run monorepo_toolkit flavor sync --from-appsIDE run configurations
Every generated workspace keeps its run configurations in one place per IDE, at the workspace root:
| IDE | Files | Committed |
|---|---|---|
| VS Code | .vscode/launch.json, .vscode/tasks.json | Yes (.gitignore keeps these two, ignores the rest of .vscode/) |
| Android Studio / IntelliJ | .run/<app>_<flavor>[_profile|_release].run.xml, .run/prepare-<flavor>.run.xml | Yes (.idea/ stays ignored) |
Each app in flavors.yaml gets <App> - <Flavor> for every flavor, <App> - <Flavor> (Profile) for development and staging, and <App> - <Flavor> (Release) for staging and production. Each one runs apps/<app>/lib/main_<flavor>.dart (main.dart for production) with --flavor <flavor>, after the shared prepare-<flavor> task (dart run monorepo_toolkit prepare --flavor <flavor>: env switch, envied regeneration and build-prepare).
Three writers produce the same files: flutter_modular_monorepo for the first app, app_scaffold for each new app, and flavor generate/flavor add here. They add only missing entries and files, so a second app merges in and your own entries and edits stay. A launch.json or tasks.json that is not a plain JSON object (comments, an array) is left unchanged, with a warning; when tasks.json is, launch.json is left alone too, because its entries run those tasks. template_base's committed files are the reference, and tests in shared_hooks and flavor_manager check both writers against them.
Projects generated before flutter_modular_monorepo 5.1.0 had un-namespaced Development/Staging/Production configs in .idea/runConfigurations/ (gitignored, so never shared). app_scaffold 2.1.0 and later removes them and their launch.json entries when they are unmodified, for whichever app they were written for, and keeps edited ones with a note to move them to .run/. It also upgrades in place the unmodified entries app_scaffold 2.0.0 and earlier wrote (a lib/... program without a preLaunchTask, and .run/ files with a buildMode option and no prepare step). flavor generate and flavor add do not upgrade them: they only add what is missing.
Android/iOS mapping
Each flavor maps to platform-specific identifiers:
| Platform | What it maps to | Example |
|---|---|---|
| Android | applicationId suffix in build.gradle | com.example.app.staging |
| iOS | Bundle identifier in Xcode scheme | com.example.app.staging |
The generate command creates all necessary native files: Android productFlavors blocks, iOS build configurations, and Xcode schemes.
Default flavors
When initializing with flavor sync --init, the default flavors are:
development(suffix.development)staging(suffix.staging)production(no suffix)
Workflow
- Define flavors globally in
flavors.yaml - Run
dart run monorepo_toolkit flavor sync --initto create the global config - Add new flavors with
dart run monorepo_toolkit flavor add - Generate native files with
dart run monorepo_toolkit flavor generate - Run the app with
flutter run --flavor development
Melos shortcuts
melos run flavor:list # List flavors for an app
melos run flavor:add # Add a new flavor
melos run flavor:generate # Generate native flavor files
melos run flavor:sync # Sync global and app configs