Skip to content

Monorepo Toolkit

Run App โ€‹

Run a Flutter app from your monorepo with interactive flavor and device selection.

Usage โ€‹

Interactive Mode โ€‹

bash
melos run run:app
# or
dart run monorepo_toolkit run

The command will:

  1. Read flavors.yaml to find available apps and flavors
  2. Run flutter devices --machine to detect connected devices
  3. Prompt you to select an app (if multiple), flavor, and device
  4. Prepare the workspace (env switch, code generation, build-prepare) unless --no-prepare is set
  5. Execute flutter run with the correct flags
๐Ÿ“ฑ Available apps:
  1. template_app

Select app [1]: 1

๐ŸŽจ Available flavors:
  1. development
  2. staging
  3. production

Select flavor [1]: 1

๐Ÿ“ฒ Connected devices:
  1. iPhone 15 Pro (ios) - 1A2B3C4D
  2. Pixel 7 (android) - emulator-5554

Select device [1]: 2

๐Ÿš€ Running: flutter run --flavor development --target lib/main_development.dart -d emulator-5554

What happens between the pick and flutter run, and what a second launch skips:

run and prepareRun a flavor and the workspace prepares itself first

Step 1 of 3, before: The workspace was last prepared for development. .env holds those values, and .prepare.state.json records the flavor and swap mode so a repeat launch can skip the slow steps.

shared/app_config/.env
# Environment configuration for developmentAPI_BASE_URL=https://dev-api.example.comAPP_NAME=MyApp Dev# โ€ฆ
.prepare.state.json
{"flavor":"development","mode":"debug"}

Non-Interactive Mode (CI) โ€‹

Pass flags directly to skip prompts:

bash
dart run monorepo_toolkit run --app template_app --flavor development --device emulator-5554

Flags โ€‹

FlagAbbrDescription
--app-aApp name (from flavors.yaml, a directory under apps/)
--flavor-fFlavor name (development, staging, production)
--device-dDevice ID (from flutter devices)
--[no-]preparePrepare the workspace before launching: env switch, envied regeneration and build-prepare for the chosen flavor (default: on). Use --no-prepare to skip

When a flag is provided, its corresponding prompt is skipped. If only one option exists (e.g., single app or single device), it's auto-selected.

Configuration โ€‹

The command reads from flavors.yaml at the workspace root:

yaml
apps:
  template_app:
    android_app_id: com.example.template_app
    ios_bundle_id: com.example.templateApp
    flavors:
      - development
      - staging
      - production

Entry Points โ€‹

Each flavor maps to an entry point. Production uses main.dart, the others use main_<flavor>.dart:

apps/template_app/lib/
  main.dart               # production
  main_development.dart
  main_staging.dart

What It Runs โ€‹

The generated flutter run command:

bash
flutter run \
  --flavor <flavor> \
  --target lib/main_<flavor>.dart   # lib/main.dart for production \
  --device-id <device_id>

The process inherits your terminal's stdin/stdout/stderr, so hot reload (r), hot restart (R), and all other Flutter CLI controls work normally.