← Articles

Monorepo setup for Flutter with Melos

By Ann Tech · 9 May 2026

A Flutter monorepo puts multiple packages in one git repository. Melos is the tool that makes this practical — it links local packages together, runs commands across all packages in parallel, and manages versioning with Conventional Commits.

When a monorepo makes sense

  • Multiple Flutter apps sharing code (e.g., consumer and admin apps)
  • A feature-based architecture where each feature is a separate package
  • A shared design system package used by several apps
  • Platform plugins with example apps

For a single small app, a monorepo adds complexity without benefit.

Setup

dart pub global activate melos

melos.yaml at the repository root:

name: my_project

packages:
  - apps/*
  - packages/*

scripts:
  # Run across all packages
  get:
    run: melos exec -- flutter pub get
    description: Get dependencies in all packages

  test:
    run: melos exec --fail-fast -- flutter test
    description: Run tests in all packages

  analyze:
    run: melos exec -- flutter analyze
    description: Analyze all packages

  gen:
    run: melos exec -- flutter pub run build_runner build --delete-conflicting-outputs
    description: Run code generation in all packages

  # Run only in specific packages
  test:unit:
    run: melos exec --scope="*_repository,*_service" -- flutter test
    description: Run unit tests only

  clean:
    run: melos exec -- flutter clean
    description: Clean all packages

Directory structure

my_project/
  apps/
    consumer/           # Consumer-facing Flutter app
      pubspec.yaml
    admin/              # Admin Flutter app
      pubspec.yaml
  packages/
    design_system/      # Shared UI components
      pubspec.yaml
    auth_repository/    # Auth data layer
      pubspec.yaml
    product_repository/ # Product data layer
      pubspec.yaml
    core_network/       # Shared networking
      pubspec.yaml
  melos.yaml
  pubspec.yaml          # Root (usually empty or workspace config)

Local package dependencies

In apps/consumer/pubspec.yaml:

dependencies:
  design_system:
    path: ../../packages/design_system
  auth_repository:
    path: ../../packages/auth_repository

Melos handles symlinking so packages resolve correctly without publishing to pub.dev.

Running scripts

# Run flutter pub get in all packages
melos get

# Run tests in all packages in parallel
melos test

# Run only in packages matching a pattern
melos test --scope="*_repository"

# Run in packages that changed since main
melos test --diff=origin/main

Versioning with Melos

Melos supports versioning based on Conventional Commits:

# Preview version bumps
melos version --dry-run

# Apply version bumps and update CHANGELOG
melos version

# Publish to pub.dev
melos publish

Commit message format:

  • feat: → minor bump
  • fix: → patch bump
  • feat!: or BREAKING CHANGE: → major bump

CI with Melos

.github/workflows/ci.yml:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: subosito/flutter-action@v2
        with:
          flutter-version: '3.24.0'
          cache: true
      - run: dart pub global activate melos
      - run: melos get
      - run: melos analyze
      - run: melos test

Common pitfalls

Circular dependencies between packages. If auth_repository imports from product_repository and vice versa, you have a cycle. Extract shared types to a core_models package that both depend on.

Not using melos exec --fail-fast. Without --fail-fast, a test failure in one package doesn't stop the run. You get a full summary at the end, but the CI log becomes hard to read. Use --fail-fast for CI, omit for local debugging.

Version skew between packages. If design_system releases a breaking change and auth_repository is not updated, the app will fail to compile. Coordinate version bumps for breaking changes and use melos version to manage them atomically.

Sign in to like, dislike, or report.

Monorepo setup for Flutter with Melos — ANN Tech