Most articles on this question end with "it depends," which is technically true and completely useless. So I will give you the rule I actually follow, and then explain it.
If you have, or plan to have, more than one frontend or CMS app, set up a monorepo. Always. The only time a single repo is the right choice is the narrow case of one frontend app paired with a CMS app, or possibly just a single frontend app on its own. That is the whole decision. Count your apps.
Why the app count is the deciding factor
The moment you have a second frontend, or a second app of any kind that shares anything with the first, you have a choice about where the shared code lives. In separate repos, that shared code becomes a publishing-and-versioning problem. You build a component library, publish it, bump versions, and keep several repos in sync by hand. Every change to something shared turns into a small release process across repositories that do not know about each other.
A monorepo removes that whole category of work. The shared code lives in internal packages that every app in the repo consumes directly. A design system, shared utilities, shared types, shared config: each becomes an owned package with a clear boundary, and changing it updates every consumer in the same commit. You get real separation of concerns without the overhead of treating your own internal code like a third-party dependency you have to publish.
That is the payoff. Not "monorepos are trendy," but that once you have multiple apps sharing code, the monorepo is simply the structure that makes the sharing cheap instead of expensive.
The signal from your dependency list
There is a connection here to how you should read a project's npm dependencies, and it is worth making explicit.
When a single app starts accumulating a large number of packages, that is often not a dependency problem at all. It is a structure problem wearing a dependency costume. A bloated package list frequently means you are building several distinct things inside one app that really want to be separated. When you hit that point, the right response is not to keep pruning packages one at a time. It is to move to a monorepo, draw the boundaries properly, and define your own internal packages so each part of the system owns its concerns.
So the package list and the repo decision are two views of the same underlying question: is this one cohesive thing, or several things pretending to be one? If it is several, the monorepo is how you stop pretending.
When a single repo is genuinely correct
None of this means monorepos are always right. They are not free. They bring tooling, workspace configuration, and a build setup that a tiny project does not need and should not pay for.
If you have one frontend app and a CMS, tightly coupled, with no second app on the horizon, a single repo is the correct and simpler choice. Adding monorepo machinery there is pure overhead solving a problem you do not have. The same goes for a lone frontend app. Keep it simple until the app count tells you to do otherwise.
That is the honest version of "it depends." It depends on exactly one thing: how many apps you have or plan to have, and whether they share code. One or two tightly-coupled apps, single repo. Anything beyond that, or anything you genuinely expect to grow, start as a monorepo and save yourself the migration later.


