I view the repo as the unit of versioning. If something has its own release cycle with its own semver number, it should be in its own repo, and vice versa. Monorepos make sense if your whole site is at a single version, as in the article. But if you want to have libraries that have stable versions (which I find useful, because it allows teams to own codebases - and I find maven is much much better than this article seems to think) then it's worth putting them in their own repositories.
As a counter-argument: I think that using a monorepo encourages a steady and careful movement of API deprecation, which is actually healthier than semver. In fact, I'll contend that semver is nothing more than an effort to bring monorepo-like bug fixes to environments that can't otherwise have monorepo-like management.
Here's the thing: if all the code is in a single repo, it's really easy for me to find all users of a given function. This means that, if I need to alter the behavior of a function, I can sanely pursue any of three options:
1. Know for a fact I can alter the behavior without impacting
anyone.
2. Refactor across the whole code base in one shot.
3. Deprecate the API and provide a replacement immediately,
then work with teams to get off the deprecated API.
In all three cases, I can trivially know exactly what I'm impacting and make a decision on how I want to impact it. As a bonus, not only can I much more directly control deprecation times, but it's dramatically less likely that one of my client programs keeps deploying with an outdated, insecure/buggy version of my library.
In my view, the whole point of semver is handling situations wherein I cannot do that. For example, if I publish a library on GitHub, it's simply not reasonable for me to know who's using my library and why. Thus, semver provides a contract between me and you: since I can't know what you're doing, I promise not to do certain things with my library so that you can use it with some confidence. But there is a cost here: it's harder for you to track upstream, it's harder for me to know who's still using what in the older library, and it's harder for me to figure out how I can help people upgrade.
I'm emphatically not saying semver is bad, but I am saying that it's deliberately compensating for source code federated across many repos. A properly managed monorepo keeps you from having to worry about it.
I think Conway's law applies: the structure of the repositories reflects the communication structure of the teams that are using them. SemVer is appropriate when you have a low-bandwidth communication channel with the other side, when it's too expensive to go into the details of what and how you need to change, so a summary is appropriate.
In an organization where everyone's familiar with and works on every codebase, you don't need that. But my experience is that codebases need to have an owning team and teams that are larger than ~12 become unwieldy, and from what I've heard from friends who work there even e.g. Facebook tends to work in smaller teams than that.
So fine, I know that the people who depend on my library are the Foo team in Australia and the Bar team in New York. But I still wouldn't want to refactor their codebase without, at least, a code review from someone on that team - in which case I want separate pull requests for the library change, the project foo change and the project bar change. And I don't want one PR to block the others, so I want to make a library release but have foo depend on the old version until their change goes through. In short I think I'd always take option 3.
You don't need a monolithic repo to do that. Just pull in the library as a git submodule, and you control exactly which version (by git commit hash) of the library you use. And in a single commit, you can change that commit hash and change the code using the library, just as you could in a monolithic repo.
With subrepos, you -- the consumer -- are still stuck with either stagnation ("stability") or you need take on a bunch of refactors whenever you update the reference to upstream.
The producer in that case is obviously completely unaware of what you're doing so they cannot make decisions based on that fact. They may, for example, deprecate an API and provide no direct equivalent because they don't know anyone's relying on it. Then you suddenly have to come up with additional code to restore an equivalent API...
The subrepo approach is OK if you're tracking some external code. In that case it's comparable to semver but possibly better integrated with your build/tooling, you win something. But if it's internal to your organization, you're hacking around what a single repo could provide you.
This is exactly the opposite of what I was arguing for. In a monolithic repo, I can see and control what the consumers are doing. Your version is actually just a way to implement semver. (Or, possibly, to do something worse than semver; subrepos by themselves, provide no stability contract, so I have to think really hard about updating my subrepos.)
And even if it were, surely they wouldn't be locked to the same version as Chrome or Android?
Basically, I think lmm and gecko are both right: there should be exactly one repository per project, where a project is defined in terms of a set of stable interfaces with the outside world. Whether the total set of stuff your company is doing should be one project or a few or many, depends on the nature of the stuff you do, what it has to deal with, and your company structure; but the answer to that should determine your repository structure.