For example, to run one or more services locally, we use a single script that sits at the repo base - ‘dev.sh service1,service2,...’. This avoids a lot of headaches for our developers, as we enforce compliance when adding a project to the repo. Lint config? One to rule them all. Test coverage thresholds? Single one. This consistency is the biggest win in my opinion.
Similarly, our integration tests are very easy to write without commit skew.
Finally, sharing libraries has been painless - since we have common/ and common/third_party/ directories at the monorepo root.
My previous job used a collection of about 6 repos for different services and such, and it was a constant struggle to ensure the correct versions were used in development - especially if you were working on a bigger feature that wasn't yet released but required "future" versions from other repositories.
Why would one want to do n pull/merge requests, n separate reviews (of related code), and n deliveries for a single evolution, is something I can't understand.
* Culture
* CI/CD tooling support
* Codebase sizes
* Devops - one repo, one deploy, let the developers figure out which repo is which.
* Developer - one codebase, let the devops people sort it out and write lots of tooling to make my monorepo work.
If this stuff was easy, everyone would be a developer.