Skip to content

Monorepo Toolkit

Workspace Setup ​

The workspace command manages Dart workspace configuration in the monorepo. Starting with Dart 3.11+, the workspace list in pubspec.yaml supports glob patterns, replacing the need to maintain an explicit path-by-path list of every package. The toolkit provides subcommands to migrate to globs, fix resolution fields, and validate workspace health.

Glob patterns (Dart 3.11+) ​

Prior to Dart 3.11, every package had to be listed individually in the root pubspec.yaml:

yaml
# Old approach — explicit list
workspace:
  - apps/template_app
  - shared/app_config
  - shared/feature_sdk
  - infrastructure/monitoring_impl
  - features/auth/auth_api
  - features/auth/auth_impl
  # ... dozens more entries

With Dart 3.11+, glob patterns let you describe an entire directory tree in a single line:

yaml
# New approach — glob patterns
workspace:
  - apps/*
  - shared/*
  - infrastructure/*
  - features/**
  - packages/**
  - utilities/**
  - devtools/**

Any package that contains a pubspec.yaml and is matched by one of the patterns is automatically included. Adding a new package to features/ no longer requires editing the root pubspec.yaml.

Subcommands ​

workspace setup ​

Migrates the root pubspec.yaml workspace list from an explicit path list to glob patterns. If the workspace already uses globs (as freshly generated projects do), it prints a notice and exits:

bash
# Migrate to glob patterns
dart run monorepo_toolkit workspace setup

# Preview changes without modifying files
dart run monorepo_toolkit workspace setup --dry-run
FlagDescription
--dry-run / -nShow what would be done without making changes

This is a one-time migration command. Once globs are in place, new packages are picked up automatically and you rarely need to run it again. It does not touch resolution: workspace, use workspace fix-resolution for that.

workspace setupDozens of workspace lines become three globs

Step 1 of 4, before: An older project lists every package in the root pubspec.yaml, so each new package is another edit. The 27 entries here are an example workspace.

pubspec.yaml
workspace:  - devtools/monorepo_toolkit  - devtools/scripts/affected  - devtools/scripts/app_scaffold  # … 20 more under devtools/scripts  - features/auth/auth_api  - features/auth/auth_impl  - shared/app_config  - shared/feature_sdk

workspace fix-resolution ​

Scans all packages matched by the workspace glob patterns and ensures each one has resolution: workspace in its pubspec.yaml. Run this after adding a new package directory or after a bulk scaffold that may have omitted the field:

bash
dart run monorepo_toolkit workspace fix-resolution

# Preview without writing changes
dart run monorepo_toolkit workspace fix-resolution --dry-run
FlagDescription
--dry-run / -nShow what would be done without making changes

workspace validate ​

Checks workspace health and exits with a non-zero exit code if problems are found. Designed for use in CI pipelines:

bash
dart run monorepo_toolkit workspace validate

Checks performed:

  1. Resolution field — every glob-matched package must have resolution: workspace.
  2. Duplicate dependency_overrides — the same package may only appear in dependency_overrides once across the entire workspace. Duplicates cause dart pub get to fail.
Exit codeMeaning
0Workspace is healthy
1One or more validation errors found

Use workspace validate in CI to catch issues before they reach other developers:

yaml
steps:
  - name: Validate workspace
    run: dart run monorepo_toolkit workspace validate

How Dart workspace resolution works ​

Dart workspaces allow all packages in a monorepo to share a single .dart_tool/package_config.json. This means:

  • A single dart pub get at the root resolves all packages.
  • Consistent dependency versions across the entire workspace.
  • Faster resolution compared to running dart pub get per package.

The resolution: workspace field in each package's pubspec.yaml opts that package into workspace resolution instead of resolving independently.

Centralizing dependency_overrides ​

Because all workspace packages share the same resolver, dependency_overrides entries from every package are aggregated. If the same package is overridden in more than one pubspec.yaml, Dart rejects the resolution with an error.

The recommended practice is to centralize all overrides in the root pubspec.yaml:

yaml
# Root pubspec.yaml — the only place dependency_overrides should live
dependency_overrides:
  some_package:
    git:
      url: https://github.com/example/some_package
      ref: main

Keep individual package pubspec.yaml files free of dependency_overrides. The workspace validate command detects duplicates and reports which packages are in conflict.

Temporarily excluding a package from the workspace ​

Sometimes you need a single package to resolve its own dependencies independently — for example, to test it against a newer version of a transitive dependency without affecting the whole workspace. Dart provides an official escape hatch: pubspec_overrides.yaml.

Place a pubspec_overrides.yaml file next to the package's pubspec.yaml with an empty resolution: value (no workspace):

yaml
# features/auth/auth_impl/pubspec_overrides.yaml
resolution:

With this file present, dart pub get treats auth_impl as a standalone package and resolves it independently. Remove the file to restore workspace membership.

TIP

pubspec_overrides.yaml is gitignored by default in Archipelago-generated projects. This keeps temporary exclusions local and prevents them from accidentally being committed.

When to run each command ​

SituationCommand
Migrating from an explicit package list to globsworkspace setup
Added a new package and it is not resolvingworkspace fix-resolution
Pre-push or CI health checkworkspace validate
Temporarily test a package in isolationAdd pubspec_overrides.yaml next to it

Melos shortcuts ​

bash
melos run workspace:setup    # Migrate to glob patterns

# No melos script for these, call the toolkit directly:
dart run monorepo_toolkit workspace fix-resolution
dart run monorepo_toolkit workspace validate