Skip to content
Back to archipelago.banuacoder.com

Core Scaffolding

How to scaffold a Flutter modular monorepo ​

Free Reference for flutter_modular_monorepo: every variable, option and package it generates. Command: archipelago generate flutter_modular_monorepo

Generate a complete Flutter monorepo with Archipelago: choose state management, networking and CI, then run the project and check the setup.

What you'll learn ​

  • Generating a complete Flutter monorepo from scratch
  • Configuring variables like state management, networking, and CI provider
  • Understanding the generated workspace structure
  • Running the generated project and verifying the setup

Prerequisites ​

  • Archipelago CLI installed and authenticated (see Installing & Setting Up)
  • Flutter SDK installed (see archipelago doctor)
  • Familiarity with Flutter project structure

Step 1: Generate the Monorepo ​

Run the generate command interactively:

bash
archipelago generate flutter_modular_monorepo

The CLI prompts you for each configuration variable. For a typical project, answer like this:

  • appName: MyApp (used for package names and display)
  • organization: MyCompany
  • domain: com (produces com.mycompany.myapp)
  • prefix: App (components become AppButton, AppCard, etc.)
  • gitProvider: github or gitlab
  • networkLibrary: dio (recommended) or http
  • stateManagement: bloc, cubit, provider, or riverpod
  • analyticsVendors and monitoringVendors, pick vendors or none
  • starterFeatures: which of introduction_sdk, auth_sdk, home_sdk, paywall_sdk to generate
  • authBackend: rest_api (default), supabase or firebase for the auth_sdk starter feature. firebase turns on isUsingFirebase. See Setting Up the Auth SDK

Step 2: Use a Config File for CI ​

For repeatable, non-interactive generation, create a JSON config:

json
{
  "appName": "Tokopay",
  "organization": "Tokopay",
  "domain": "com",
  "prefix": "Tp",
  "prefixCasing": "pascalCase",
  "gitProvider": "github",
  "networkLibrary": "dio",
  "isUsingWebSocket": false,
  "websocketLibrary": "dart",
  "isUsingFirebase": false,
  "analyticsVendors": [],
  "monitoringVendors": [],
  "isUsingFeatureFlags": false,
  "featureFlagVendor": "none",
  "stateManagement": "bloc",
  "starterFeatures": ["introduction_sdk", "auth_sdk", "home_sdk", "paywall_sdk"],
  "authBackend": "rest_api",
  "includeGenerated": false
}

Then run:

bash
archipelago generate flutter_modular_monorepo --config tokopay_config.json

Step 3: Explore the Generated Structure ​

The brick generates a full Dart workspace:

text
tokopay/
├── apps/
│   └── tokopay/              # Host app with two-phase init
│       ├── lib/
│       │   ├── di/injector.dart
│       │   ├── host/initializers/
│       │   ├── router/app_router.dart
│       │   ├── main_development.dart
│       │   └── main_staging.dart
│       └── fastlane/         # iOS/Android build lanes
├── shared/
│   ├── feature_sdk/          # FeatureManifest, FeatureSDK, registry
│   ├── locale_core/          # Shared locale state
│   └── router_registry/      # Route registration
├── infrastructure/           # Network, monitoring, analytics SDKs
├── features/                 # Feature modules (auth, home, etc.)
├── packages/                 # UI kit, shared deps
├── devtools/                 # Monorepo toolkit scripts
└── pubspec.yaml              # Workspace root

Step 4: Resolve Dependencies and Run ​

bash
cd tokopay/apps/tokopay
flutter run --flavor development -t lib/main_development.dart

The generator already ran dart pub get, build_runner and slang. Run them again only if a step logged a warning. The host app reads every feature manifest in the pre-launch phase. Pre-launch (DI, routes) runs before the first frame. Post-launch (analytics, flags) runs after.

Step 5: Verify the DI Setup ​

Open apps/tokopay/lib/di/injector.dart. It holds the global GetIt wiring:

  • Global: SDKs and infrastructure (network, monitoring, analytics), plus one global module per feature
  • Feature container: each feature keeps its repos, datasources and usecases in its own child GetIt, built when its shell page opens

Each feature global module registers a const FeatureManifest and a lazy SDK. The host never imports feature internals.

Run the generated composition-root test to check the wiring:

bash
cd apps/tokopay
flutter test test/di/injector_test.dart

Key Configuration Choices ​

VariableEffect
networkLibrary: dioGenerates Dio-based HTTP client with interceptors
networkLibrary: httpGenerates dart:http-based client
isUsingWebSocket: trueAdds WebSocket SDK package to infrastructure
isUsingFirebase: trueIncludes Firebase init in bootstrap
analyticsVendorsGenerates analytics_sdk plus one impl per vendor
monitoringVendorsGenerates one impl per vendor. monitoring_sdk is always generated.
stateManagementPicks the state-management variant for every feature brick
gitProvider: githubCreates .github/workflows/ CI templates
gitProvider: gitlabCreates .gitlab-ci.yml instead

Next Steps ​