How To Manage A Flutter Monorepo With Multiple Packages

Flutter category image

Here is how to manage a Flutter monorepo with multiple packages and melos instead of using shell scripts.

I have some private Flutter packages in single repositories on GitHub. And because they are private, I had some authentication issues with transitive dependencies. But then someone guided me into another direction → monorepo. Here is a quick start guide of how to manage a Flutter monorepo with multiple packages and melos.

To be honest, I haven’t done that for years because it’s way easier to manage small repos. But thanks to melos, the effort is actually not that high for me. It only took me around an hour of learning and setup. However, I can add new packages without having to change anything in the configuration. It works out of the box.

In this article, I want to give you a short introduction of how I manage my monorepo with melos.

My goal

For my purpose, I basically have this one goal

New code must not break anything

Changes come via pull requests and can only be merged when the quality checks pass. Here is what I am aiming for

  • All tests pass (means running flutter test in every package)
  • All analyzers pass (means running flutter analyze in every package)

I could write a shell script for that and it would be easy. But if the repo grows I might run into problems in the future. That’s why I tried melos.

What is melos?

Melos is a tool used for handling Dart projects that contain multiple packages, often called mono-repos. It is currently being developed and is used in projects like FlutterFire.

Melos lets multiple packages operate within a single repository while still keeping them independent from each other. Its features include:

  • Automatically creating new versions and changelogs.
  • Automatically publishing packages to pub.dev.
  • Connecting and setting up local packages.
  • Running commands at the same time across different packages.
  • Showing a list of local packages and what they depend on. Melos is also very useful in CI/CD environments for automating complex tasks and solving challenges.

Check out the website for more details. They even support IDE integrations.

Melos setup

  1. Install melos
    Run dart pub global activate melos and make sure to add it to your PATH variable so that you can access it from anywhere with your preferred CLI tool.
  2. Create a pubspec.yaml in your root folder of your repository
    Set the name and environment properties (see below)
  3. Add a melos dev dependency You can do this with the command dart pub add melos --dev.
YAML
name: a_project

environment:
  sdk: '>=3.1.3 <4.0.0'
  
dev_dependencies:
  melos: ^6.0.0

4. Create a melos.yaml and configure your workspace
Tell melos about your repository structure like this so that it can find your packages.

    YAML
    name: some_project
    
    packages:
      - core/**
      - services/**

    5. Bootstrap your project
    melos bootstrap does the job. Your packages are now properly linked and the fun stuff can begin.

        Melos is now successfully linked with all your packages. Let’s create some automation scripts!

        Melos scripts

        Let’s start with my final melos.yaml and then I explain what I did:

        YAML
        name: my_project
        
        packages:
          - "core/**"
          - "services/**"
        
        command:
          bootstrap:
            usePubspecOverrides: true
        
        scripts:
          analyze:
            run: melos exec -- "flutter analyze"
            description: Analyze all packages
        
          test:
            run: melos exec --dir-exists=test -- "flutter test --coverage"
            description: Run tests for all packages

        In the scripts block you can define sections that melos can execute. I defined two sections analyze and test. To execute them, you can use the command melos run <script>.

        My scripts are simple. Run flutter analyze and flutter test --coverage. Together with the melos exec command, this is already enough to reach my goals. They will be run on all found packages in the folders and subfolders of core or services in my repository.

        You can learn more about scripts here.

        Automate with CI and melos

        Now that we have configured melos and created scripts, we can integrate this entire process also in a build pipeline.

        For GitHub, there is the bluefireteam/melos-action available which sets up melos in the CI environment and bootstraps it for you. Otherwise, you have to perform the install and setup steps like on your local machine to get it running.

        Here is an example GitHub Actions pipeline that uses melos. It runs the Dart analyzer on all packages and executes all tests.

        YAML
        name: Pull Request
        
        on:
          pull_request:
            branches:
              - master
        
        jobs:
          build:
            runs-on: ubuntu-latest
        
            steps:
            - uses: actions/checkout@v3
        
            - name: Setup Flutter
              uses: subosito/flutter-action@v2
              with:
                flutter-version: '3.19.6'
                channel: 'stable'
        
            - name: Setup melos
              uses: bluefireteam/melos-action@v3
        
            - name: Run code analysis for all packages
              run: melos run analyze
        
            - name: Run unit tests for all packages
              run: melos run test

        With that you can ensure quality standards before any new code arrives in your repository.

        What else?

        Melos can even do more for you.

        • Create a changelog based on commit messages
        • Create releases
        • Publish new package versions to pub.dev

        All this can also be configured and automated. Check out the guides on the melos website for more details!

        Conclusion

        In this article I gave a brief introduction of how to manage a Flutter monorepo with multiple packages and melos. You could, of course, just write your own shell scripts and leverage existing tools for that. But I assume that you will run into problems sooner or later. It’s not a coincidence that so many big players in the Flutter world use melos.

        Related articles


        Leave a Reply

        Your email address will not be published. Required fields are marked *