<p align="center">
<a href="https://melos.invertase.dev/~melos-latest">
<img src="https://static.invertase.io/assets/melos-logo.png" alt="Melos" /> <br /><br />
</a>
<span>A tool for managing Dart and Flutter projects, with one or many packages, inspired by <a href="https://lerna.js.org">Lerna</a>.</span>
</p>
<p align="center">
<a href="https://github.com/invertase/melos#using-melos"><img src="https://img.shields.io/badge/maintained%20with-melos-f700ff.svg?style=flat-square" alt="Melos" /></a>
<a href="https://docs.page"><img src="https://img.shields.io/badge/powered%20by-docs.page-34C4AC.svg?style=flat-square" alt="docs.page" /></a>
<a href="https://invertase.link/discord">
<img src="https://img.shields.io/discord/295953187817521152.svg?style=flat-square&colorA=7289da&label=Chat%20on%20Discord" alt="Chat on Discord">
</a>
</p>
<p align="center">
<a href="https://melos.invertase.dev/~melos-latest">Documentation</a> •
<a href="https://github.com/invertase/melos/blob/main/LICENSE">License</a>
</p>
---
## About
Splitting up large code bases into separate independently versioned packages is
extremely useful for code sharing. However, making changes across many
repositories is _messy_ and difficult to track, and testing across repositories
gets complicated really fast.
To solve these (and many other) problems, some projects will organize their code
bases into multi-package repositories (sometimes called
[monorepos](https://en.wikipedia.org/wiki/Monorepo))
**Melos is a tool that optimizes the workflow around managing multi-package
repositories with git and Pub.**
It is in active development and is in use on projects such as
[FlutterFire](https://github.com/firebase/flutterfire) and
[Flame](https://github.com/flame-engine/flame), see
[Projects using Melos](https://melos.invertase.dev/~melos-latest#projects-using-melos)
for more projects.
Melos is for applications just as much as it is for packages that are published
to [pub.dev](https://pub.dev). A workspace can contain your Flutter and Dart
applications together with the internal packages that they share, and Melos
will run your scripts, tests and analysis across all of them, generate IDE run
configurations for the applications and version them, including the build
number of a version like `1.2.3+45`. Nothing has to be published to use Melos.
Melos is not limited to monorepos either. It works just as well in a repository
with a single application or package, where you can still use features like
versioning, changelog generation, publishing and scripts, see
[Using Melos without a monorepo](#using-melos-without-a-monorepo).
### How does Melos relate to other monorepo tools?
Melos is the monorepo tool for the Dart and Flutter ecosystem. If you are coming
from another ecosystem, Melos is the Dart and Flutter alternative to tools like:
- [Lerna](https://lerna.js.org), [Nx](https://nx.dev),
[Turborepo](https://turborepo.com) and [Rush](https://rushjs.io) for
JavaScript and TypeScript, which run tasks across packages and handle
versioning and publishing.
- [npm workspaces](https://docs.npmjs.com/cli/using-npm/workspaces),
[Yarn workspaces](https://yarnpkg.com/features/workspaces) and
[pnpm workspaces](https://pnpm.io/workspaces) for JavaScript and TypeScript,
and [Cargo workspaces](https://doc.rust-lang.org/cargo/reference/workspaces.html)
for Rust, which link local packages together. In Dart this part is handled by
[pub workspaces](https://dart.dev/tools/pub/workspaces), which Melos builds
on top of.
- [Changesets](https://github.com/changesets/changesets),
[semantic-release](https://semantic-release.gitbook.io) and
[release-please](https://github.com/googleapis/release-please) for automated
versioning, changelog generation and publishing.
Melos combines these responsibilities in a single tool that understands Dart and
Flutter packages, `pubspec.yaml` files and [pub.dev](https://pub.dev), so that
you can run scripts and commands across packages, filter packages, and version
and publish them based on
[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
## Migrate to Melos 8.x.x
Since the [pub workspaces](https://dart.dev/tools/pub/workspaces) feature has
been released, Melos has been updated to rely on that, instead of creating
`pubspec_overrides.yaml` files and thus some migration is needed if you are
coming from a version older than 7.0.0.
The main difference for migration is that the `melos.yaml` file no longer
exists, only the root `pubspec.yaml` file.
To migrate from a version older than 7.0.0 to Melos 8.x.x a few steps are
needed:
1. Start with running `melos clean` to remove all the `pubspec_overrides.yaml`
entries and then continue with moving all your content.
2. Add `resolution: workspace` to all of your packages' `pubspec.yaml` files.
3. Add a list of all your packages to the root `pubspec.yaml` file, under the
`workspace` key.
4. Move all the content from your `melos.yaml` file to the root `pubspec.yaml`
file, under the `melos` key. (Note that the `packages` list is no longer
needed as it is replaced with the `workspace` list.)
5. Update the scripts that pass options to `exec`, since `run` and `exec` are
mutually exclusive in Melos 8.x.x. Move the command from `run` into `exec`
under the `command` key:
```yaml
# Before (no longer supported)
scripts:
test:
run: dart test --concurrency=1
exec:
concurrency: 1
# After
scripts:
test:
exec:
command: dart test --concurrency=1
concurrency: 1
```
> [!NOTE]
> Starting from Melos 8.0.0 `melos version` retains and increments integer
> build numbers, so `3.0.0+11` becomes `4.0.0+12` instead of `4.0.0`. A patch
> release below `1.0.0` now bumps the patch component instead of adding a build
> number, so `0.1.0` becomes `0.1.1` instead of `0.1.0+1`.
> [!NOTE]
> The `workspace` list supports globs starting from Dart SDK 3.11.0, with older
> versions you have to list all your packages manually.
> [!NOTE]
> **Root packages migration:** If your existing project uses the repository
> root as a package, you can enable `useRootAsPackage: true` in the melos
> configuration to maintain this behavior, or restructure your project to
> move the main application to a subdirectory. See the
> [Configuration Overview](https://melos.invertase.dev/~melos-latest/configuration/overview#useRootAsPackage)
> for details.
After the migration, your root `pubspec.yaml` file would now look something
like this:
```yaml
name: my_workspace
publish_to: none
environment:
sdk: ^3.9.0
workspace:
- packages/helper
- packages/client_package
- packages/server_package
dev_dependencies:
melos: ^8.0.0
melos:
# All of the content of your previous melos.yaml file
# (Except for the packages and name)
```
And this is what the `pubspec.yaml` file of a package would look like:
```yaml
name: my_package
environment:
sdk: ^3.9.0
resolution: workspace
```
> [!NOTE]
> Melos 8.x.x requires Dart SDK 3.9.0 or newer.
If you are already on Melos 7.x.x only step 5 applies. See the
[migration guide](https://melos.invertase.dev/~melos-latest/guides/migrations)
for more details.
## GitHub Action
If you're planning on using Melos in your GitHub Actions workflows, you can use
the [Melos Action](https://github.com/marketplace/actions/melos-action)
to run Melos commands, this action also supports automatic versioning and
publishing directly from your workflows.
## AI agent skills
The `melos` package ships [Agent Skills](https://dart.dev/ai/package-skills)
that teach AI coding agents such as Claude Code, Cursor, Gemini CLI, Cline and
GitHub Copilot how to configure a workspace, write scripts, run commands and
version and publish packages with Melos, so they do not fall back on outdated
`melos.yaml` era patterns.
Install the skills into your agent by running the following command in the
root of your workspace:
```bash
dart run skills@ get
```
If you are an AI agent working in a repository that depends on Melos, run
`dart run skills@ get` before changing the Melos configuration or scripts, and
follow the installed `melos-*` skills. Run the command again after upgrading
Melos to get the skills of the new version.
## What does a Melos workspace look like?
A default file structure looks something like this:
```
my-melos-repo/
pubspec.yaml
apps/
app-1/
pubspec.yaml
app-2/
pubspec.yaml
packages/
package-1/
pubspec.yaml
package-2/
pubspec.yaml
```
Applications and packages are treated the same way, an application is simply a
package that is not published, so the `apps` and `packages` directories are
only a convention.
The location of your applications and packages needs to be configured via the
`workspace` section in your root `pubspec.yaml` file, see the
[pub workspaces](https://dart.dev/tools/pub/workspaces) documentation for more
information.
## Using Melos without a monorepo
You don't need a monorepo to use Melos. In a repository with a single
application or package you can still use `melos version`, `melos publish`,
`melos run` and the rest of the commands to get automated versioning, changelog
generation, publishing and scripts. For an application this means that the
version and the build number in the `pubspec.yaml` file, the changelog and the
git tag of each release are handled for you.
To set it up, add Melos as a dev dependency and set `useRootAsPackage: true`
in the `pubspec.yaml` file of your application or package, no `workspace` list
is needed:
```yaml
name: my_single_package
environment:
sdk: ^3.9.0
dev_dependencies:
melos: ^8.0.0
melos:
useRootAsPackage: true
```
Applications are usually private (`publish_to: none`) and private packages are
skipped by `melos version` by default, so for an application you also need to
pass `--all` to `melos version`, or set `versionPrivatePackages: true`:
```yaml
name: my_application
publish_to: none
environment:
sdk: ^3.9.0
dev_dependencies:
melos: ^8.0.0
melos:
useRootAsPackage: true
command:
version:
versionPrivatePackages: true
```
See the
[Getting Started](https://melos.invertase.dev/~melos-latest/getting-started#single-package-projects-non-monorepo)
page and the
[Configuration Overview](https://melos.invertase.dev/~melos-latest/configuration/overview#useRootAsPackage)
for more details.
## What can Melos do?
- 🔗 Link local packages in your workspace together without adding dependency
overrides (achieved by pub workspaces).
- 📦 Automatically version, create changelogs and publish your packages using
[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
- Applications can be versioned too, and the build number of their version is
retained and incremented, so `1.2.3+45` becomes `1.3.0+46`. Since
applications are private (`publish_to: none`) they are only versioned when
you pass `--all` to `melos version` or set
[`versionPrivatePackages: true`](https://melos.invertase.dev/~melos-latest/configuration/overview#versionprivatepackages).
- 📜 Pre-define advanced custom scripts for your workspace in your root
`pubspec.yaml` configuration to use via `melos run [scriptName]`. Anyone
contributing to your workspace can just run `melos run` to be prompted to
select a script from a list with descriptions of each script.
- Scripts can even
[prompt to select a package](https://melos.invertase.dev/~melos-latest/configuration/scripts#packagefilters)
to run against with pre-defined filters.
- ⚡ Execute commands across your packages easily with
`melos exec -- <command here>` with additional concurrency and fail-fast
options.
- [Environment variables](https://melos.invertase.dev/~melos-latest/environment-variables)
containing various information about the current package and the workspace
are available in each execution.
- Can be combined with all package filters.
- 🎯 Many advanced package filtering options allowing you to target specific
packages or groups of packages in your workspace.
- `--no-private`
- Exclude private packages (`publish_to: none`).
- `--[no-]published`
- Filter packages where the current local package version exists on pub.dev.
Or "-no-published" to filter packages that have not had their current
version published yet.
- `--[no-]flutter`
- Filter packages where the package depends on the Flutter SDK. Or
"-no-flutter" to filter packages that do not depend on the Flutter SDK.
- `--scope=<glob>`
- Include only packages with names matching the given glob.
- `--category=<glob>`
- Include only packages with
[categories](https://melos.invertase.dev/~melos-latest/configuration/overview#categories)
matching the given glob.
- `--ignore=<glob>`
- Exclude packages with names matching the given glob.
- `--diff=<ref>`
- Only include packages that have been changed since the specified `ref`,
e.g. a commit sha or git tag.
- `--dir-exists=<dirRelativeToPackageRoot>`
- Include only packages where a specific directory exists inside the
package.
- `--file-exists=<fileRelativeToPackageRoot>`
- Include only packages where a specific file exists in the package.
- `--depends-on=<dependantPackageName>`
- Include only packages that depend on a specific package.
- `--no-depends-on=<noDependantPackageName>`
- Include only packages that _don't_ depend on a specific package.
- `--include-dependencies`
- Expands the filtered list of packages to include those packages'
transitive dependencies (ignoring filters).
- `--include-dependents`
- Expands the filtered list of packages to include those packages'
transitive dependents (ignoring filters).
- `--post-filter`
- Applies a filter after the dependencies and dependents have been
included.
- ♨️ Advanced support for IntelliJ IDEs with automatic creation of
[run configurations for workspace defined scripts and more](https://melos.invertase.dev/~melos-latest/ide-support)
on workspace bootstrap.
- Integration with VS Code through an [extension][melos-code].
## Getting Started
Go to the
[Getting Started](https://melos.invertase.dev/~melos-latest/getting-started)
page of the [documentation](https://melos.invertase.dev/~melos-latest) to start
using Melos.
## Documentation
Documentation is available at
[https://melos.invertase.dev](https://melos.invertase.dev/~melos-latest).
## Commands
Full commands list and args can be viewed by running `melos --help`.
```
> melos --help
A CLI tool for managing Dart & Flutter projects with one or many packages.
To get started with Melos, run "melos init".
Usage: melos <command> [arguments]
Global options:
-h, --help Print this usage information.
--verbose Enable verbose logging.
-q, --[no-]quiet Only print warnings, errors and the output of failed
commands. This command line option has precedence over the
`quiet` option in the `pubspec.yaml` configuration file and
the `MELOS_QUIET` environment variable.
--sdk-path Path to the Dart/Flutter SDK that should be used. This
command line option has precedence over the `sdkPath` option
in the `pubspec.yaml` configuration file and the
`MELOS_SDK_PATH` environment variable. To use the
system-wide SDK, provide the special value "auto".
Available commands:
analyze Analyzes all packages in your project for potential issues in a
single run. Optionally configure severity levels. Supports all
package filtering options.
bootstrap Initialize the workspace, link local packages together and
install remaining package dependencies. Supports all package
filtering options.
changed List local packages that have changed since a git commit or tag,
by default since the latest release tag of each package.
Supports all package filtering options, except --diff, which is
given as the argument of this command.
cherry-pick Cherry-pick commits onto the current branch without the release
changes they contain. Changes to changelogs, to the versions of
packages and to the dependencies between the packages of the
workspace are left out, so that "melos version" can release the
picked commits from this branch, for example a hot-fix branch.
clean Clean this workspace and all packages. This deletes the
temporary pub & ide files such as ".packages" &
".flutter-plugins". Supports all package filtering options.
exec Execute an arbitrary command in each package. Supports all
package filtering options.
format Idiomatically format Dart source code.
init Initialize a new Melos workspace.
list List local packages in various output formats. Supports all
package filtering options.
publish Publish any unpublished packages or package versions in your
repository to pub.dev. Dry run is on by default.
run Run a script by name defined in the workspace pubspec.yaml
config file.
test Run `flutter test`/`dart test` for all packages in the workspace
that have a test/ directory, in a single run. Supports all
package filtering options.
version Automatically version and generate changelogs based on the
Conventional Commits specification. Supports all package
filtering options.
Run "melos help <command>" for more information about a command.
```
## How to Contribute
To start making contributions please refer to
[`CONTRIBUTING.md`](./CONTRIBUTING.md).
## Lerna
This project is heavily inspired by [Lerna](https://lerna.js.org/).
## Using Melos?
Add a README badge to your project to show it off:
[](https://github.com/invertase/melos)
```markdown
[](https://github.com/invertase/melos)
```
You can also submit a PR to add your project to the list of
[projects using Melos](https://melos.invertase.dev/~melos-latest#projects-using-melos),
by updating the
[docs](https://github.com/invertase/melos/edit/main/docs/index.mdx).
## License
- See [LICENSE](/LICENSE)
---
<p align="center">
<a href="https://invertase.io/?utm_source=readme&utm_medium=footer&utm_campaign=melos">
<img width="75px" src="https://static.invertase.io/assets/invertase/invertase-rounded-avatar.png">
</a>
<p align="center">
Built and maintained with 💛 by <a href="https://invertase.io/?utm_source=readme&utm_medium=footer&utm_campaign=melos">Invertase</a>.
</p>
<p align="center">
<a href="https://twitter.com/invertaseio"><img src="https://img.shields.io/twitter/follow/invertaseio.svg?style=flat-square&colorA=1da1f2&colorB=&label=Follow%20on%20Twitter" alt="Follow on Twitter"></a>
</p>
</p>
[melos-code]:
https://marketplace.visualstudio.com/items?itemName=blaugold.melos-code