
Monorepo is great if you're really good - mr_crankypants
https://yosefk.com/blog/dont-ask-if-a-monorepo-is-good-for-you-ask-if-youre-good-enough-for-a-monorepo.html
======
cbanek
> the entire code base got forked, and the entire org is now held hostage by
> the dumbass.

> Of course in a Good team, needless dependencies would be weeded out in code
> reviews, and a Culture would evolve over time avoiding needless
> dependencies.

Really, the one consistent thing is that if you have a good team, you'll make
it work no matter what tech or decisions you make (assuming you're also good
enough to know when you've lost and change course), and if you're a bad team,
you're doomed to failure, because, well, you're bad (by definition).

I think this article also vastly underestimates the cost and annoyance of the
tooling of CI'ing a large number of repos, especially if you have to match or
do some kind of cross product on the feature branches. (such as, repo A branch
B can only be built with repo C branch F, but all the other repos should be
master)

~~~
thaumasiotes
>> Of course in a Good team, needless dependencies would be weeded out in code
reviews, and a Culture would evolve over time avoiding needless dependencies.

Heh. This reminded me of a different story, which I remember vaguely enough
that I'll paraphrase from memory:

> "The Excel team will never go for it. Their motto is 'Find the
> dependencies... and eliminate them.'"

> This probably explained why the Excel team had its own C compiler.

~~~
mixmastamyk
Sounds like Joel on Software.

~~~
oblio
[https://www.joelonsoftware.com/2001/10/14/in-defense-of-
not-...](https://www.joelonsoftware.com/2001/10/14/in-defense-of-not-invented-
here-syndrome/)

------
DanFeldman
My team just switched to a monorepo. It's been only a few weeks, so I can't
claim any results yet, but we've lived w/ the pain of poly-repo for long
enough that we were ready to invest in a single repo.

We've spent a lot of time building and iterating a unified ci/cd environment
to support the new repo. Previously each project had it's own
test/deploy/build/publish story and usually it's own jenkins project. Now,
each project is registered and triggers its own steps. Cross-project edits can
happen in a single pull request. We have an incredible amount of integration
tests (more so than unit tests), and getting them to work corss-project while
migrating has been challenging.

We've gone from ~10-15 actively maintained repos to about 3 as we're slowly
migrating. We have a mix of services, libraries, and batch processing all
mixed in.

The authors points about forking and long-lived branching being incredibly
difficult for most teams is really crucial. We're going to have to invest in
education for new members about WHY we have a monorepo, what it means for your
development, and how to change your perspective for developing at HEAD. I
don't think 'bad' developers make it easier or harder. Instead, clearly
articulating behaviors that exist in a poly-repo vs mono-repo world to
developers is the Differentiator.

These articles were absolutely crucial to developing our monorepo.

[https://trunkbaseddevelopment.com/](https://trunkbaseddevelopment.com/)

[http://blog.shippable.com/ci/cd-of-microservices-using-
mono-...](http://blog.shippable.com/ci/cd-of-microservices-using-mono-repos)

[https://www.godaddy.com/engineering/2018/06/05/cicd-best-
pra...](https://www.godaddy.com/engineering/2018/06/05/cicd-best-practices/)

~~~
joshschreuder
How do you handle building changes to just one of those projects? Can Jenkins
do that (easily)?

I think that's the big thing that always puts me off monorepo... We'd
basically be going from ten 5 minute builds to one 50 minute build if it
wasn't possible to do incremental builds. IIRC Google and MS have purpose
built tools that do impact detection to work out what to build for their
monorepos to keep build times down.

~~~
kevan
If you're doing a monorepo I think it's strongly implied that you'll also use
a build system (Blaze/Brazil/BuildXL etc) that has granular compilation units
and output caching so build time doesn't scale linearly with the company's
total codebase.

It's definitely important to consider before jumping in. Going from 5m to 50m
compile times would be a major issue for me.

~~~
sagarm
Err what is even the alternative? Even a makefile would provide incremental
builds.

~~~
Too
A _good_ makefile provides incremental builds in _every possible scenario_ of
source file changes. It's very easy to write bad makefiles that don't catch
modified or removed header files, or even worse when code generation or other
complicated build logic is involved. Because a lot of developers seem to think
"random build fail? oh just do make clean" is an acceptable workaround.

------
jnurmine
Is the monorepo/multirepo choice really the most important thing to consider?

Branching: monorepo or not, if a feature-incomplete development branch for one
of the supported targets can "hold the entire organization as a hostage" then
the SCM people, and/or persons responsible of the SCM policy, should do some
introspection...

Why are deliveries done from a branch which is obviously still in development?
Why does code-to-be-released need to depend on incomplete work? Why aren't
something like "topic branches" used?

Modularity: monorepo or not, problems will certainly appear when the
complexity of implementation outpaces the capacity created by the design. To
get modularity, one needs actual modules with properly designed (=not brittle,
DRY, KISS, YAGNI, SOLID, etc. etc.) interfaces between the modules. Now, does
monorepo/multirepo really play a role here at all? If everyday changes are
constantly modifying the module interfaces in incompatible ways which breaks
existing code, this speaks something about the design, or rather the
insufficiency of it.

Of course, every project and team is different. However, even if a locally
optimal choice for the monorepo vs. multirepo question is found, problems
existing regardless of monorepo/multirepo will still be there.

~~~
jknoepfler
I was wondering the same thing. Like, I use a microservice architecture at
work, but the choice of using one vs. many git repos to represent diffs in
those services over time seems largely meaningless. I don't like large diffs
or people breaking production, but this is solved by testing and insisting
upon small diffs, not by how many git repos we use.

Formally speaking, multi-repo management allows a strict subset of the diffs
allowed to a mono-repo (because diffs can 't extend beyond each repo root).
Are the excluded possibilities all bad? No. Are they generally bad? Not
really. Are they sometimes bad? Sure. Are they sometimes better than many
diffs across many repos? Sure. Can a reasonably competent dev team tell the
difference? Sure, usually. Unsurprisingly, this usually requires the exact
same tooling as ensuring the quality of microrepo changes.

If you're continuously deploying master, have a healthy ci/cd pipeline, and
enforce good merging discipline, you're fine either way.

I'm a little tired of doing things like revving our trace and logging
libraries across our 50+ micro repos that represent microservices. That's
genuinely obnoxious. Is it bad? No. Is it obviously more or less error prone
than the equivalent monorepo update? No. All the bad bits of either strategy
just require some tooling and a clear head.

------
jasim
Linus Torvalds said something about this, in relation to microkernels. But the
gist is in how interactions between many pieces makes the whole thing complex.
Here's the quote from his book "Just for Fun".

"The theory behind the microkernel is that operating systems are complicated.
So you try to get some of the complexity out by modularizing it a lot. The
tenet of the microkernel approach is that the kernel, which is the core of the
core of the core, should do as little as possible. Its main function is to
communicate. All the different things that the computer offers are services
that are available through the microkernel communications channels. In the
microkernel approach, you’re supposed to split up the problem space so much
that none of it is complex. I thought this was stupid. Yes, it makes every
single piece simple. But the interactions make it far more complex than it
would be if many of the services were included in the kernel itself, as they
are in Linux. Think of your brain. Every single piece is simple, but the
interactions between the pieces make for a highly complex system. It’s the
whole-is-bigger-than-the-parts problem. If you take a problem and split it in
half and say that the halves are half as complicated, you’re ignoring the fact
that you have to add in the complication of communication between the two
halves. The theory behind the microkernel was that you split the kernel into
fifty independent parts, and each of the parts is a fiftieth of the
complexity. But then everybody ignores the fact that the communication among
the parts is actually more complicated than the original system was—never mind
the fact that the parts are still not trivial. That’s the biggest argument
against microkernels. The simplicity you try to reach is a false simplicity."

~~~
bartread
> "...The simplicity you try to reach is a false simplicity."

Also applies to some microservice architectures I've seen. People completely
disregard the complexity (and overhead!) of the interactions between
microservices.

~~~
asdfman123
I feel like I've become a crusader against microservices for the same reason.

They're so easy to set up and they immediately solve problems. But they also
create many more, which aren't immediately obvious. And very few people are
willing to say, "I was totally wrong to move to them, and let's spend some
more precious time rolling them back."

~~~
atoav
As somebody who built some stuff with microservices before, I think the key
is, that you don't view any architectural pattern as a silver bullet. All
things come with their own trade offs.

It can make totally sense to break out certain parts into their own
microservices if you thought long and hard about the interface and which data
is going to be passed around – but if you break things out into their own
microservices just for the heck of it, you will end up in a very messy mess
quickly.

Using microservices to solve problems which don't demand them is similar to
using OOP patterns in places where they are known to bring pain: you are
holding a hammer and you think the world is made of nails.

That beeing said I am sure this has nothing to do with the real practicality
of the underlying patterns, it just shows how easy people can lie to
themselves.

------
sandGorgon
>>>* They don't like to have to clone lots of other repos, and to then worry
about their versions (in part because the tooling support for this might be
less than great).*

I think this is the argument around which the whole post is made. Everyone
does want to work in a small space where they control everything. I want to
see git log with just my code commits - so I'll make a microservice out of it.

All other arguments are just there to wrap this one. I think it's wrong.

At an organisational level, a monorepo is more good than bad because it
simplifies dependency management and makes for a low-ego team.

~~~
humanrebar
Counterpoint: monorepos make it easier to neglect packaging and dependency
management since it's mechanically possible to assume any files in source
control are on-hand. This makes it trivial to have implicit dependencies and
see the uglier implications of Hyrum's Law.

------
willeh
I don't agree with the author that the quality of the team is what determines
if a mono-repo is appropriate or not. It doesn't really matter if you use a
mono-repo or not, what matters is what individual engineers are empowered to
do.

If engineers or even team-leads don't have permission to create a repo
themselves well then you're probably going to see benefits from a monorepo.

At the same time if you have say a ~100 people sharing a repo then you have to
make sure that you have tooling that allows each team to customize their
building and test environments themselves, which is hard because many CI
solutions assume that One Repo = One Build status. Implicit in the author's
reasoning is the principle that good engineers don't make mistakes; they don't
break the build, not ever. But of course they do, everyone does, and if you
have a hundred developers builds will be broken and people's productivity
ruined.

Perhaps because we're an industry so prone to failure we keep looking for that
one solution, that given a good team makes all problems go away. Agile, XP,
Monorepos, Containers, Microservices: we tell ourselves will solve our
problems and get those pesky business people off our backs for good. But they
won't and never will.

What really matters is enablement, how can we get our code into production
doing what it was intended to do without having your toes stepped on all the
time. If you design your processes and tooling around enablement not the
cargo-cult flavour of the month buzzword invented in the modern beautifully
architected, yet completely open office spaces of one of the FAANG companies,
then maybe then you can get some actual results.

~~~
marcosdumay
> Implicit in the author's reasoning is the principle that good engineers
> don't make mistakes; they don't break the build, not ever.

They don't, ever, because the VCS refuses a push if it breaks the build.

That's the problem with all those single-repo discussions. It works perfectly
well if you have all the tooling that makes a single repo work like a multi-
repo.

And it's great because you can enforce behind the scenes that everything is
coherent... Except that you can enforce the same thing on a multi-repo if you
write the equivalent tooling. All the points are completely moot, except the
one that if you don't have a ton of tooling, a single-repo won't work at all,
while a multi-repo will just be not great.

~~~
YawningAngel
I actually tend to find the opposite - with a multi repo, CI/CD is often just
plain broken and people waste significant amounts of time cargo culting
working setups (and often do so badly or don't keep up with upstream changes).

------
wellpast
> Monorepo is great if you're really good, but absolutely terrible if you're
> not that good. > Multiple repos, on the other hand, are passable for
> everyone – they're never great, but they're never truly terrible, either.

The calculus is trickier than this.

He thinks the above is true because of this other thing he says:

> With multiple repos, modularity is the norm.

But if this were true, being "Good" would be easy. I wish programming tools
were this able. Then I could go to the pool every day!

But just because you're using some feature of a build or programming system --
like modules or classes or namespaces -- doesn't mean you get the win.
Certainly doesn't mean you know how to wield these tools.

In the end the technical feature doesn't save you. You actually have to have a
hard-earned skill, which is how to properly modularize code into stable
components with narrow stable interfaces and all of that. This skill is very
rare ime.

Now back to monorepo vs modules.

If you use modules but you suck at modularization you're going to be paying a
huge tax. Because you'll be creating volatile code/interfaces and you'll have
to go through a process each change. You will be amplifying the tax from your
lack of skill that you wouldn't if you were just in a single monorepo.

On the other hand if you use a monorepo and you suck, you won't experience
^^this^^ pain and you'll be at a much higher probability of staying sucking.

In short, programming language and build features don't bestow skills.

------
justinmchase
Its funny and makes some good points but I don't think the distinction is
between good and bad teams but whether or not you're 1 team or more.

If one team has one application that is split across multiple repositories it
can be a productivity boost and a simplification to unite them into a single
repo with some single tools and norms.

If you have two teams working primarily on two sets of repos and two different
systems or applications, by all means split them into two (or more) repos.
Just be cause its called a "monorepo" doesn't mean you can't have more than
one!

It may be simpler to have one, it may be simpler to have many. Do whats
simpler for you! I happen to think that it primarily depends on how your teams
are organized more than on who is in the teams or their "badness" levels.

~~~
AmericanChopper
I think this only works if the teams are actually working on different
products. If Team A and Team B are both writing to and reading from the same
data stores, then I’d say they’re likely both working on the same product, and
you have a multirepo.

------
RHSeeger
> What do you do when you have a branch working on Android and another branch
> working on iOS and you have deliveries on both platforms? You postpone the
> merge, and keep the fork.

Honestly, it never occurred to me that you're deploy from more than one
branch. If you can't merge the branches into <your main branch that releases
are built from>, then what's in the branch doesn't make it into a release
(from my experience).

~~~
larrik
Seriously, this part threw me hard. Having multiple active forks is not
something that's ever been considered as an option anywhere I've worked.
Worse, I'm not convinced multi-repo even fixes this issue if you already have
a culture that allows multiple active forks.

For instance, big app rewrite, half-new REST API on the backend. Oh, but we
need to maintain the old app APIs for those who can't update (like
SuperImportantCustomer). Better fork!

~~~
rurounijones
I suppose it depends on your definition of "active" here but having release
branches for previous major versions that are still supported with things like
backported security fixes etc. is a pretty common setup.

------
ThePhysicist
Does anyone here have experience using submodules to tie individual
repositories together? We've been using this in our small startup (only a few
developers) and so far it works nicely. It allows us to check out and develop
repositories individually but at the same time maintain an exact dependency
graph for our entire system. You can for example have a single repository that
ties together different projects and has submodules that contain specific
references e.g. to the frontend, backend and deployment repositories. You can
then use this master repository e.g. for deployment and integration testing.
Gitlab makes CI/CD in such a setup very easy and checks out submodules
recursively during a build, even across groups.

The drawback is that not many people are familiar with submodules and they can
be a bit tedious to set up, though working with a submodule is almost like
working with a normal file in git. One danger is of course that branching
between individual submodules can get messy. Another nuisance might be that
you have to commit recursively, i.e. if you have one repository with a
submodule to which you make changes you need to first commit these changes in
the submodule and then create a new commit in the parent repository that adds
the new version of the submodule. Maybe this is a good thing though as it
forces you to commit changes individually in each submodule before committing
a larger change into your main repository. In general I would avoid nesting
submodules more than two levels deep, as this can quickly get confusing.

In the past I've also worked on a large mono-repositoriy and enjoyed it as
well, just curious to hear if anybody has used submodules in a larger team.

~~~
the_gipsy
I have bad experiences with submodules. It was only one submodule just one
level deep, and it only contained something like a convoluted configuration
shared among multiple repos.

As you say, getting a change first into the child and then into the parent
requires double PRs and testing. But that's the same as if you had it as a
package dependency. Only that instead of a version, you have a sha1 which you
never know what it is.

I prefer package dependency, because it forces you to explicitly make a
release, where it should have passed PR and some integration tests. Also merge
conflicts are clearer.

------
theamk
That is very, very subjective

> With multiple repos, modularity is the norm. It's not a must - you
> technically can have a repo depending on umpteen other repos. But your
> teammates expect to be able to work with their repo with a minimal set of
> dependencies.

You'd think so.. but no. I am working with multi-repo project where some repos
have about dozens of dependencies, all developed locally, and interdependent
on each other. Bumping the basic repo is very hard and frustrating. I miss my
monorepo every day, where I could just make a PR and fix all consumers at
once, where I had a CI which would test all modules at once.

------
aboodman
One interesting new thing in this post that I've not seen in this debate is
that polyrepos tend to enforce acyclical dependency graphs.

All monorepo projects I've ever worked on enforced the same either through the
language involved or mechanically, and it was universally a good thing.

------
qznc
Does anybody know some monorepo horror stories?

I have heard plenty of people complain about their many-repo structure and
wishing for a monorepo. I would like to hear some concrete story where a
monorepo went wrong. This article is just abstract opinion.

~~~
mr_tristan
Oh yes. #1 problem I've experienced at multiple places: delaying integration
with tons of branching.

Usually the PM or PO force everyones to using some vague "product version"
they track for public releases. Places that use monorepos well tend to have
very few branches (like, maybe 2 or 3), which have nothing to do with your
public product versioning scheme, and instead use "branch by abstraction" to
stay integrated.

But what I end up seeing, is that the product team and middle management gets
involved with dictating version control, e.g., "this will be version 1.2, and
then that should be 2.3, ok let's cut those branches...", and then they change
their minds as some team has to delay and before another is ready. And then
bugs start rolling in from both testing and they don't know what to do, and
they start asking people to just "get it done", and then, things _really_
start falling apart. You add 10+ teams trying to use branches for their own
work based off of god knows what and it becomes a mess of crazy integration
problems.

I seriously think that a huge benefit of multiple repositories, is that is
scares the pseudo-technical managers and product people into not bothering
with trying to track or dictate usage of the version control system.

~~~
the_gipsy
Or you could just tell them to stay off versioning/release/branching
discussions, even in a monorepo. All they need to know is what release/deploy
has what features, and when the release happens.

~~~
mr_tristan
Easy to say when you're starting from scratch, but in all of my cases, these
were "pre-existing conditions", i.e., was in place before I joined, and it
took a long time to get people to see the light. It gets real tricky when
you're _not_ a manager, and you're basically asking other managers to stop
having such a loud voice in things.

Just another case of "culture eats strategy for breakfast". Once people start
using any particular versioning strategy, it becomes canon, even if it's a
terrible way to organize.

~~~
the_gipsy
Yeah sorry if I came off as dismissive. It's usually a long process, if that's
how things run.

------
cjfd
I think one should not underestimate the powers of the not-so-good-team to
make anything go sour. Who says the not-so-good-team isn't going to make sure
that any change needs to touch at least 3 repos and quite regularly as many as
10?

As for the philosophical issue that yosefk raises, I generally advocate
solutions that work for the case that the team is good. I tend to think that
if the team is not good you would be cooked anyway. Also, if you raise the
stakes people might actually start learning a bit.

------
hinkley
> In a Good team, you don't have multiple concurrent branches from which
> actual product deliveries are produced, and/or where most people get to
> maintain these branches simultaneously for a long time.

These sorts of Black and White, naked assertions drive me nuts. Buried in this
statement is an assumption that the only software model worth even discussing
is SaaS software - all copies of the code being run are run by your team, so
master@HEAD is our ground truth at all times (except during deployments, which
BTW are happening at least 10 minutes out of every hour of every day...)

Teams that sell applications or allow self-hosting, or even some SaaS shops
with large enough customers are going to have to maintain multiple release
branches. Possibly for years. From personal experience, anything above 3 seems
to become unsustainable. But having 3 repos (a monorepo with 2 active branches
+ master) may be the right answer for you. One can't work, and 100 is murder.
Stop the pendulum in the middle.

------
cj
> If you agree with the above, the choice is up to your personal philosophy.
> To me, for instance, it's a no-brainer

The most obvious issue with this post is it fails to acknowledge that for any
production scale company, you can't blindly say that a decision like this is a
choice of personal philosophy (unless you're starting a brand new project from
scratch, in which case, spending tons of time structuring repos well probably
isn't your first priority since new projects have very little code).

I'd love to see more articles that discuss repo structure in the context of a
pre-existing codebase with hundreds of thousands of lines of production code
and 10+ engineers collaborating on it.

For anyone reading: I'd be interested to hear anecdotes from people working at
companies that have successfully (or unsuccessfully) re-structured a monorepo,
the reasons you did it, how much time was invested in the restructure, and
whether you think it was a net positive long-term.

------
reilly3000
I think the whole idea of simplicity vs complexity, and the linked article
"Worse is Better" is fundamentally ill-conceived. Simple vs. Complex is
contextually relative. Literally every observer is subject to their own
opinion of a design. Success in the wild = success. I think success in the
wild, especially in our age of information overload, depends on being
"convenient to understand and operate".

A 'simple' solution may not be easy to grok. Few people think at the level of
axioms.

A survivable solution must be passed along to many people across generations.

For some, monorepos are simple because that is what they know, for others
multirepos are the norm. The survival of the firms that adopt these strategies
will somewhat dictate what repo strategy propagates in the world, not the best
design.

------
sally1620
What author misses is that multi-repo is also not dumbass proof. Our team of
about 60 people owned about 5-6 git repos that compiled into one SO. Every
simple bug fix required multiple diffs to multiple repos.

The real argument that the author is making is that worse is better. Monorepo
requires good tooling and a disciplined team. Multi-repo is worse but it is
easier to manage when dealing with inexperienced programmers who want to have
their own repo for their shiny little microservice.

IMO, the difference is that multi-repo has limitations and mono-repo has
challenges. You will never get atomic commits and precise versioning in multi-
repo. With mono-repo, there are a lot of challenges that can be solved with
good engineering.

------
rezmason
Ask your doctor if Monorepo is right for you.

~~~
ghostbrainalpha
Individual results may vary. Don't take Monorepo if you are bad at
programming, or if you may become bad at programming.

Side effects include but are not limited to your repo growing into a single
giant ball of circular dependencies.

~~~
newshorts
Monorepo may cause blindness, sleep deprivation and suicidal thoughts. If you
experience any of these symptoms, stop taking monorepo and consult your
manager.

~~~
asark
If you experience a build lasting more than six hours, seek rockstar ninja
help immediately.

------
kazinator
Let's assume without proof that Glibc developers are good. Similarly,
kernel.org developers are good as are the gcc.gnu.org people.

Should glibc, gcc and the kernel be in a monorepo?

(Cue laugh track ...)

~~~
dboreham
Did you just invent the unikernel?

~~~
teddyh
AFAIK, Unix did this, so BSD Unix did this, and the modern BSD derivatives
still do this.

------
burtonator
One thing that's nice about a monorepo is if the language has modules. It it
supports modules well you can isolate your code better but still keep it in
one large repo.

I dislike having all my code under one 'src' directory and it's nice to have
modules like foo-ui and foo-util and so forth. Knowing that one module doesn't
use ui components is nice because you can use it on the backend for example.

But it's all fully integrated and tested together.

------
dboreham
Always makes me think of a philips radio my Dad told me about called the "Mono
Knob". It had a complex design that allowed control via just one knob. He said
they were always in the shop for repair when he worked as a teenager in a
radio store.

[https://www.thevalvepage.com/radios/philips/785ax/785ax.htm](https://www.thevalvepage.com/radios/philips/785ax/785ax.htm)

------
hinkley
One of the tenets of XP that survived (or should I say, is amplified?) into
CI/CD is the idea that you should build up callouses for painful activities
instead of trying to avoid them.

In that context, if a thing is tough but has value, you make a path to it.
First make the tools consistent, and then make people consistently use the
tools. The more predictable the system becomes (predictability is the opposite
of magic!), the more you insist on people using it. Pushback is a kind of
feedback, and you have to address at least some of the concerns of people who
refuse ('meet me halfway here').

Someday it will shock no-one to say that Git is not the best of all possible
version control tools. If this is difficult, it may not be the people. Maybe
it's time to start thinking about the next version control system?

SVN had some pretty decent facilities for monorepos. Some people will tell you
that Git traded some of these features for others, but looking through the
information architecture documentation for git, I don't think I can agree.
Some of that information is there, it's just maybe not packaged for
consumption.

------
jayd16
>bad fork

How is this an argument? You merge the unforked projects and its the
equivalent to multirepo. I don't follow the argument at all.

...I started writing rebuttals to the others but I guess when your argument is
"yeah you can do it right but you _could_ do it wrong and I have defined the
question in such a way that we err on success for multi-repo and err on
failure on mono-repo" I can't really fight that.

------
scarejunba
You're just pushing your trouble into a shadow layer that's hidden. You still
have just as much complexity. It's just not encoded.

If branch A on repo X will only work with branch B on repo Y, you're holding
that relationship in an uncoded way. It's true and unrepresented, and you
never want that.

------
galkk
I've experienced 3 large codebases with different approaches:

1\. Monorepo: Google3

2\. Non monorepo, large pile of #@$: Microsoft Exchange

3\. Non monorepo, Amazon

After working with them, from my personal experience, monorepo was the best.
Yes, Google has ton of internal stuff and they could go away with not using
much of external dependencies, but when everything works, it works like a
charm. Convenience of defining protobufs/contracts, ease of reference them and
ton of the things are given to you when you're in the system.

At Google I never felt that the system is hostile to you. It was extremely
easy to start hacking something if you'd like to. Yes, it's not only monorepo,
but the overall quality of the tools available, but monorepo is also quite a
significant part of it.

------
yongjik
> With multiple repos, modularity is the norm. (...) With a monorepo,
> modularity is a mere ideal.

> ...

> In a not-so-good team, your monorepo will grow into a single giant ball of
> circular dependencies.

Sounds like the author was lucky enough to not encounter a not-so-good team
with multiple repos.... :D

------
jsw
I’m firmly on team monorepo, and I agree great tooling is an absolute
requirement. We use Bazel + AWS CodeBuild with local caching. We have an
average incremental CI build of our monorepo that’s under 45 seconds. Clean
build 30+ minutes.

------
jupp0r
There is also a way to simultaneously reap the drawbacks of monorepos and
multirepos: consolidate numerous small repos into somewhat big monorepos and
then don't merge everything into one big repo.

This way, you'll have to deal with

* difficult tooling

* dependency hell between the mono repos (which are now way more tightly coupled due to the dependency graph between them being denser)

* long living branches causing way more collateral damage as described in the original article

* cross-repo changes have become even harder for all the reasons above

You get all the bad things and avoid those advantages! Welcome to my world :)

------
lootsauce
I feel like I’m missing something. Never used monorepo before but looking into
it for our node code base. It seems like the combination of a monorepo and
individually publishing the packages to a private npm server such as nexus
eliminates many of these issues. One project can remain using an older version
while another can use a breaking change. Pin your versions and follow semver
and you should be fine. What am I missing here?

------
tudelo
Coming from a small company with a monorepo to a large team with a monorepo,
it seems to work fine. But maybe I need to be exposed more to other workflows.

------
mark_l_watson
My primary language now is Common Lisp and I have one mother of all mono repos
for all of my personal Common Lisp code. I set the root of this repo as a
Quicklisp load point so all my libraries and applications are available with a
Quicklisp load. Life is good.

I don’t quite get the point of this article though. I am a very enthusiastic
but not rockstar programmer, and I don’t have problems with a large mono repo.

~~~
gumby
But you're one person. The article argues that a single repo is unmanageable
when you have _many_ devs working at the same time.

------
ar_lan
I find this article more compelling than Yossi's article:
[http://blog.shippable.com/our-journey-to-microservices-
and-a...](http://blog.shippable.com/our-journey-to-microservices-and-a-mono-
repository)

Yossi's comes off extremely pretentious, without really explaining why people
consider multi-repo projects to begin with.

------
dmitriz
> like Google, the ultimate force for Good in technology

Hahaha...

[https://www.reddit.com/r/degoogle/](https://www.reddit.com/r/degoogle/)

[https://twitter.com/hashtag/degoogle](https://twitter.com/hashtag/degoogle)

------
TheGRS
There's some nuggets of good things to look out for in here, but "don't do
monorepo because your team is full of dumbasses" feels like a useless
argument, maybe even a little adversarial. Monorepos solve versioning problems
_very_ effectively, which would be a pro if you're worried about working with
dumbasses.

------
dmitriz
> What do you do when you have a branch working on Android and another branch
> working on iOS and you have deliveries on both platforms?

Stop it and focus on one single web app instead that anyone can run. Unless
your app is going to be in the top 10 that people can't miss downloading.

------
rosstafarian0
Is being demeaning and rigid just the cool thing to do today in blogs. I feel
like I keep reading articles like this every day now. "Well if your team is
full of dumbasses" or "If you use OO instead of functional programming"

~~~
NikkiA
Have you not noticed that this is the new norm everywhere?

------
epage
This reminds me of some the trade-offs I've looked at with monorepos:
[https://epage.github.io/dev/monorepos/](https://epage.github.io/dev/monorepos/)

------
drudru11
So glad Yosef keeps writing on his blog. This is a well articulated gem. I had
intuition as to why the monorepo style was not great for most shops. His
clever argument nails it.

------
JamesBarney
Ugh I don't like his use of the word dumbass. Coding is hard, it's easy to
break things. We've developed lots of tools of strategies so we don't have to
rely on people getting it right every time.

Branching: getting forked by your worst programmer This example seems
contrived I've never worked anywhere where having a fork that works for some
scenarios and not others is tolerated for long. This would be given the
highest priority.

Modularity: demoted from a norm to an ideal This is basically saying a multi-
repo makes it hard to reuse your own code which increases modularity. I find
devs on very large projects are already reticent to reuse code from other
projects/teams, but this pushes them even farther to rewrite domain logic that
should probably be shared. In most cases I'd trade a little bit of modularity
for increased domain logic consistency.

Tooling: is yours better than the standard? There are few organizations that
have so much code they break available source control solutions but
simultaneously don't have the technical expertise to manage a monorepo that
large. For these I guess it makes sense to break it up into manageable peaces
based on the relationships between your projects.

I've worked on subpar teams that decided against monorepo and it was a
nightmare. It took forever to get setup, the build time was days, and cross
repo edits were painful. They regretted going multi-repo.

~~~
CannisterFlux
The branching example is very tempting when you have a product that is used on
site by multiple customers. Customer A asks for some change that impacts
customer B. Without good tests the easiest thing to do is fork the world for A
and B, so the changes only impact one. Then you gradually drift apart. Add
customer C, D, E... and it gets really fun.

With multiple repos it gets even crazier. You have forks for A and B that work
with some other software repo, maybe common, maybe forked itself. Soon you
have wiki pages with compatibility matrices, common libraries that
mysteriously break with minor changes despite being battle tested ... for some
set of versions.

~~~
lmeyerov
Re:Branching, having lived this, monorepos are very much a blessing, not a
curse.

If software is big enough to force considering monorepos, then cross-cutting
dependencies will happen, and then one diffable long-lived monobranch is much
better than a bunch of interleaved ones.

Incrementally building, landing, etc., cross-cutting deps becomes much less of
a slog. Ex: skip concerns about versioning of _internal_ APIs.

The other issue I had was the sleight-of-hand on build modules. Yes, you don't
need good devs to speed up incremental builds b/c you can search/build in each
project. But if you want to run 20 modules together to test/experience them,
good luck, esp. for interactive modes. (Congrats, you reinvented the
monorepo!)

