Live data from Hacker News

Ask HN: What are the pros / cons of using monorepos?

news.ycombinator.com

51–60 of 100 posts

Re: Ask HN: What are the pros / cons of using monorepos?

#51
I’ve pondered the same thing in my time working for web startups.

I think a good goal to instead shoot for is being able to extremely trivially build and ship a “latest” of your entire product.

You know your product doesn’t grow in sane predicable ways, and you know you won’t have resources dedicated to maintaining internal dependencies, so why try to half-ass a complex internal dependency tree? What ALWAYS happens is unexpected feature requests break clean APIs setup by engineers, which creates all this fake work of “making the breaking change” across the dozens of dependents.

Something like a monorepo could help prevent issues like this, but it’s not a guarantee you’re making it easier to ship one latest version of your software.

Re: Ask HN: What are the pros / cons of using monorepos?

#52
Monorepos:

- Work best when you have an open culture

- PCI compliance will be annoying

- The obvious--everything in one place

- Need good tooling around keeping master building

- As they grow, become an uphill battle to use with an IDE

- Test are likely to slow down as the repo grows, so tooling around tests

- Usually lead to a rats nest of dependencies

- Third-party library upgrades can be painful

- Coupled with CD (and it really needs to be coupled with CD), it's easy to get surprise breaks

Multirepos:

- Every team will need to dabble in build and release engineering

- Changes across repos are slow and painful (I claim this is a feature because it makes you think about versioning and deployment)

- Library developers have to think more about versioning

- You'll probably need a binary repository like Artifactory

- More time and tooling needed to do library upgrades (especially interesting for security issues)

- Harder for people to switch teams

Re: Ask HN: What are the pros / cons of using monorepos?

#53

Things that change together, go together. Monorepos prevent people from having to dig in all imaginable places of your version system to find all pieces of your application. At the same time, if you have 10 micro services which are accessed by 1 frontend, it may be a little bit messy to keep all that code in the same place. Common sense (which is not that common) is what should be used to determine. Ask yourself some…

>At the same time, if you have 10 micro services which are accessed by 1 frontend, it may be a little bit messy to keep all that code in the same place.

Why is this messy? Using folders to separate your code has no intrinsic organizational difference than using an entire repo. There's no issue in throwing every app in your company under one repo and just using a folder to organize your stuff.

Separating code into multiple repos makes one repo less aware of changes in another repo. It actually makes things harder and worse.

This is the same issue with monoliths and microserves. You don't need to separate your code into several computers just for organizational issues. You can use folders to organize things.

Re: Ask HN: What are the pros / cons of using monorepos?

#54
post #36

Earlier quoted context omitted.

Even with untyped, I'd argue that you want it to be in your face that you cannot change the front and the back ends together. Getting them in one commit will not get them in one deploy.

In mono/mulirepo debates, I frame this as multirepos make hard, scary things hard. Monorepos make it easy to introduce changes that break APIs at deploy time, but are hidden by the atomic commit actually being OK.

I think API versioning is orthogonal to how you organize your code. If you have multiple repos, then you still have that "atomic commit" where you update the version of the client library and adjust the code to handle the new semantics. It then breaks when you deploy it to production because the server code isn't deployed yet (or vice versa).

Basically, if you make RPCs, breaking up your repositories or combining your repositories doesn't eliminate this problem. It's a separate problem that you have to tackle. The reason it doesn't come up as often as it should is because a lot of code is liberal in what it accepts, and most changes are strictly additive (i.e. it's "add more information to the response", not "remove information from the response", because we're generally pushed in the direction of making our applications do more). But it is something you have to attack head-on. No tool will auto-fix the problems for you.

Re: Ask HN: What are the pros / cons of using monorepos?

#55
post #26

Pros: * Single version / branching for everything * Commits that go across components/apps are atomic. Cons: * When it gets big, those features matter less * Churn from other dev's stuff gets in your merge/rebase work. * 'git log' and other commands can be painfully slow * Mistakes in the repo (e.g., committing a password) now affect many more people. Use for highly-coupled source bases. Where releases together and a…

> Churn from other dev's stuff gets in your merge/rebase work Wouldn't other people' work only cause issues if they are changing the same files, in which case conflicts would happen even if the work is spread in multiple repos?

Here is the problem:

1- You finished your work, so you pull from the central repository, and merge your your branch to the master

2- You do your merge work, test it a bit and commit

3- Now, you push and oops, another team did the same, you are now left with to heads

4- You merge or rebase the two heads. Probably a simple task, but you may still need to run some tests again. And if you are lucky, you are done, otherwise, back to step 3

Also, if you are rebasing before push, you should be able to keep a clean history. However, if you are merging, and there are good reasons for a "merge only" policy, you are going to have a mess of merge commits every time the previous situation happens.

That's something you can work around with good management. But the more freedom you give individual teams to push to the common branches, the more that situation will arise, the more you try to control access, the more chance you will have for teams to go in different directions, making the merges infrequent but tricky.

Re: Ask HN: What are the pros / cons of using monorepos?

#56

Monorepos: - Work best when you have an open culture - PCI compliance will be annoying - The obvious--everything in one place - Need good tooling around keeping master building - As they grow, become an uphill battle to use with an IDE - Test are likely to slow down as the repo grows, so tooling around tests - Usually lead to a rats nest of dependencies - Third-party library upgrades can be painful - Coupled with CD…

Can you expand your comment on PCI compliance?

We've had to go through similar-to-PCI compliance hoops for our monorepo, and settled on a solution that didn't degrade the median developer's velocity too much.

I'm curious to know what other monorepo companies had to go through to satisfy the compliance people.

Re: Ask HN: What are the pros / cons of using monorepos?

#57
post #46

I've worked in environments across the version-control gamut. The best-run places have had monorepos. But, for the life of me, I would not trust the companies that didn't have monorepos, to operate a monorepo. To go mono is to make an org-level engineering/cultural commitment, that you're going to invest in build tools, dependency graph management, third-party vendoring, trunk-driven development, and ci/cd infrastruc…

What would be a scalable open-source monorepo stack? Git, Gitlab, Bazel?

Re: Ask HN: What are the pros / cons of using monorepos?

#58
post #26

Pros: * Single version / branching for everything * Commits that go across components/apps are atomic. Cons: * When it gets big, those features matter less * Churn from other dev's stuff gets in your merge/rebase work. * 'git log' and other commands can be painfully slow * Mistakes in the repo (e.g., committing a password) now affect many more people. Use for highly-coupled source bases. Where releases together and a…

> Churn from other dev's stuff gets in your merge/rebase work Wouldn't other people' work only cause issues if they are changing the same files, in which case conflicts would happen even if the work is spread in multiple repos?

I think it can still happen though.

Imagine you're in a branch for large project P. You want to merge to trunk but there are conflicts. The upstream library project L was changed in your branch but not in merged down by the submitter.

Even if P simply relies on a binary of L that is already in the artifact store, you still have to deal with merging this code down when normally you wouldn't.

In fact, the much bigger issue is that you now must deal with the double edged sword of updating the entire org when a shared dependency must be updated.

Perhaps you even completed that task in your project branch. Now you get to deal with merging into every project in the org that was touched.

Re: Ask HN: What are the pros / cons of using monorepos?

#59
Having experienced both the monorepo approach (at Google and Lyft's L5 autonomous division) the and manyrepo approach (at Lyft's main rideshare division), my conclusion is that keeping as much code in a single repository as possible (i.e. a monorepo) is generally the best approach.

The downside of manyrepos is that you often have to merge multiple changes into different repos in order to achieve a single logical change, and each of these changes requires a code review, waiting for CI, etc. For example, you may have a library that is shared by several services that your team owns. If you want to change some logic that lives in the library and propagate that change to a service, you have to make the change in the library and then bump the library version in the service. The latter change, while simple, is pure busywork, and at Lyft this second step easily adds 1-2 hours of overhead between waiting for code reviews and waiting for CI. Monorepos therefore make it much easier to share code and meaningfully reduce overhead for your team.

One of the cited downsides of monorepos, VCS scalability, only really kicks in for very large teams. At Lyft L5, we have a single shared Git monorepo hosted on GitHub that hundreds of engineers contribute to daily, and to my knowledge we haven't hit serious problems with Git itself (although I last worked in that org about a year ago). We did run into a few peripheral issues though:

- People kept inadvertently merging things that broke master. This would happen when two incompatible changes were merged at nearly the same time, or two incompatible changes were merged a few days apart but the second change was based off a stale master from before the first change, so tests pass on the branch but not after merge. We ended up solving this by having "deliver" branches that are basically master branches for a single team; if you break the deliver branch the only people you have to answer to are your immediate teammates, and it doesn't stop all other merges across the org. Deliver branches are periodically merged into master by a release manager who handles merge conflicts.

- CI got progressively slower. We addressed this by making improvements to the build system, optimizing tests, granularizing dependency graphs, using C++ idioms like forward declarations and PImpl to reduce dependency chains, and so on.

If you have a monorepo, you probably want to use a tool like Bazel. And since Bazel is, to my knowledge, the best tool in the world for doing what Bazel does, that means you probably want to use Bazel. Bazel has you specify your dependency structure as a DAG, and then allows you to quickly re-run tests on PRs based only on the code that changed. It also makes builds for C++ and other compiled languages blazingly fast, and if you're building C++ I don't think there's a better build system out there, monorepo or no. Bazel is a complex tool though so I'd encourage you to read through its highly detailed user manual, and if you have any questions ask on Stack Overflow where you'll often get a response directly from one of the core maintainers.

Re: Ask HN: What are the pros / cons of using monorepos?

#60
I won't try to be exhaustive here, but I think it's worth mentioning a few things:

One con is that most open source (as well as publicly available but proprietary) tooling is geared towards the non-monorepo approach. So if you want to use a monorepo, you're going to have to fight a bit of an uphill battle because most tools and processes assume you have lots of little repos. For example, build triggers in a lot of CI/CD tools operate on a per-repo basis.

There are some random benefits - it's easier to make everything public-by-default, which encourages people to look at source code written by other teams, and creates a culture of transparency and internal openness.

But the big thing in my opinion isn't directly the monorepo itself, but what's known inside Google as the "One Version Rule"[1]. Basically this means that only a single version of any package should be in the repo at a time. There are exceptions, but that requires going to extra effort to exempt your package from this rule.

I guess Chrome and Android are examples of this - they are made up of lots of little Git repos that are stitched together, but they generally follow the One Version Rule. On the other hand, if you just stick a lot of npm modules in there and every single one has a separate package.json file, then it's technically a "monorepo" but it's not following the One Version Rule.

You also need good test coverage. Not just in terms of line coverage or some other artificial metric, but to the point where you could say "I feel reasonably comfortable that a random change will be caught by my tests". This lets people in other teams catch regressions without having to have a detailed understanding of your team's codebase.

So once you've got these three things - 1) a monorepo 2) with everyone following the One Version Rule and 3) lots of tests - it means that dependency owners can update all of their consumers at once without much effort. They just make a change to their base library, and the build system will walk the dependency tree and figure out all the consumers that could possibly break, and runs all the appropriate regression tests.

This is the inverse of how it normally works at large companies, where each team pulls in their dependencies and pins them to a specific version. At most companies, updates require extra effort, so the default is to let everything go stale. This is especially problematic when security vulnerabilities are released (e.g. to an ancient version of jQuery) but teams can't update until they migrate off of an old API. It also means that library owners regularly have to maintain multiple old branches for months or even years after the initial release, because everyone's too afraid to update.

I personally think it's a myth that you need to be "Google scale" to benefit from a monorepo. In my opinion, you only need a few tens of repos before all the different combinations of semvers get unweildy. For me, going from Google's monorepo to a company that is built around lots of little repos in GitHub Enterprise felt like going back to the CVS/RCS days, where every single file had a separate revision number and changes weren't made atomically.

[1]: https://opensource.google/docs/thirdparty/oneversion/

Post reply on HN