Skip to content

Guides

Flutter monorepo template: a production-ready structure you can generate ​

Short answer. A good Flutter monorepo template gives you one Git repository with a Dart workspace, an app that only wires things together, one package per feature, shared packages below them, and the scripts and CI to run it all. You can copy such a repo from GitHub, or generate one with archipelago create. A generated project has your names in it from the first commit, and you can add features to it later.

To build the workspace by hand, step by step, read Flutter monorepo with Melos. This page is about what a ready-made one should contain, and what Archipelago generates.

What a Flutter monorepo template should contain ​

Check these before you pick one, including ours.

  1. A workspace root. One pubspec.yaml with a workspace: list, so every package resolves its dependencies together.
  2. Layers with one direction. The app depends on features, features depend on infrastructure, infrastructure depends on shared code. Nothing points upward.
  3. One package per feature. Teams can change a feature without touching the others.
  4. Wired dependency injection and routing. A new feature should register itself. You should not edit a central file for each one.
  5. Flavors and environment files. Development, staging and production builds from the first day.
  6. Scripts for the whole repo. Analyze, test, format and code generation across all packages.
  7. CI and release lanes. Pipelines that run the scripts, and a way to ship to the stores.
  8. A check for the rules. A command that fails when a package imports something it should not.

Many GitHub templates cover the first three. Fewer cover the last five. See Flutter boilerplate generators compared for how the common options differ.

The layout Archipelago generates ​

This is the real layout of the reference app that every Archipelago brick is written from. The root pubspec.yaml lists these folders in its workspace: section:

yaml
workspace:
  - apps/*
  - devtools/**
  - shared/*
  - packages/*
  - infrastructure/*
  - features/**
  - utilities/*
text
my_app/
├── apps/my_app/             # the Flutter app: bootstrap, flavors, fastlane/
├── features/                # one folder per feature, for example auth/, home/, paywall/
├── infrastructure/          # SDK wrappers: network, analytics, monitoring, storage
├── shared/                  # feature_sdk, router_registry, app config, l10n
├── packages/                # UI kit and asset packages
├── utilities/               # app_utilities, app_lints
├── devtools/                # the monorepo toolkit, runs without the CLI
├── .github/workflows/       # CI (or .gitlab-ci.yml)
├── build_prepare.yaml       # which debug packages are swapped out per flavor
├── flavors.yaml             # flavor definitions
├── CLAUDE.md, AGENTS.md     # instructions for AI coding assistants
└── pubspec.yaml             # workspace root and Melos scripts

A feature with its own API for other features splits into two packages. This is the auth feature:

text
features/auth/
├── auth_api/lib/src/        # the port other features may use: AuthSDK, AuthGuard, AuthStatus
└── auth_impl/lib/src/
    ├── data/                # datasources, repositories, token store
    ├── domain/usecases/
    ├── presentation/        # pages and cubits
    ├── router/              # the feature's routes
    └── di/                  # its own container and global module

Each feature has its own dependency injection container, and registers its routes before the router is built. The Dual-GetIt pattern and feature registration explain how.

Generate one ​

Install the CLI, sign in, and create the project:

bash
dart pub global activate archipelago_cli
archipelago auth login --interactive
archipelago create --output ./my_app

create writes a config file for you to edit. Set the app name, the state management (bloc, cubit, riverpod or provider), the network library, and GitHub Actions or GitLab CI. Then press Enter. For CI or scripts, pass the file with --config. All options are in Getting Started.

Then link the packages and run the app:

bash
cd my_app
melos bootstrap
flutter run

Scripts in the generated repo ​

These are scripts in the root pubspec.yaml. They run across all packages:

bash
melos run analyze
melos run test
melos run graph:validate     # fails if a package imports against the layer rules
melos run di:check           # fails if the injector file drifts from the registered modules
melos run flavor:add         # add a flavor
melos run env:switch         # switch environment files

The devtools/ folder lives in your repo. It runs in CI with no dependency on the Archipelago CLI. See Monorepo Toolkit. Coverage tooling is part of Pro, and affected-package detection is part of Enterprise.

Add a feature later ​

A template repo is a copy, so adding the tenth feature is manual work. In a generated project you run one command:

bash
archipelago generate feature_monorepo_skeleton

It makes an empty feature package that is registered the same way as the others. Or add a finished one such as auth_sdk. The Brick Catalog lists all 76 bricks: 50 Free, 20 Pro and 6 Enterprise. The live catalogue is at archipelago.banuacoder.com/bricks.

When not to use Archipelago for this ​

  • Your app is small. One developer, a few screens and no plan to grow: a single package is easier to read than a workspace. Start with flutter create.
  • You want no account. You need a free account to download bricks. Very Good CLI does not ask for one.
  • You already have a structure you like. If your team has its own layout, use plain Mason for single bricks or keep your own template.
  • You do not want a monorepo. The generated project is a workspace with many packages. It takes time to learn.
  • You need a finished app to reskin. This is a structure to build on, not a ready-made vertical app.

FAQ ​

What is a Flutter monorepo template? ​

It is a starting repository for Flutter that holds the app and many packages together, with the workspace, scripts and CI already set up. You build your product inside it instead of creating the structure yourself.

Is a template repo or a generator better? ​

A template repo is a copy, and its history is not related to the original, so you cannot merge later fixes. A generator writes files with your names and settings and can add features later. A template repo is better when you want to read all the code first and your project is small.

Does the generated monorepo use Melos? ​

Yes. The root pubspec.yaml holds the Dart workspace and the Melos scripts. There is no separate melos.yaml.

Can I use it for free? ​

Yes. The Free plan gives you 3 project scaffolds per month and the Free bricks. See pricing for Pro and Enterprise.

Can I change the generated code? ​

Yes. It is plain Flutter and Dart code in your repo. When you upgrade a brick, the CLI stops if you changed its packages and offers a merge. See Upgrading generated packages.

Try Archipelago

Make a free account, install the CLI, and generate a project:

dart pub global activate archipelago_cli
archipelago auth login --interactive
archipelago create --output ./my_app

The Free plan includes 3 project scaffolds per month and the Free bricks. See Getting Started for each step, and pricing for Pro and Enterprise.