On the other day a new frontend developer joined the company and started opinionating that micro-frontend structure should be used rather than the monorepo that we were using.
I thanked him for showing us an alternative method, but couldn't argue back because I hadn't thought why did we use Monorepo.
So let's say we're creating a new FE project. What structure strategy shall we use? What strategies are available?
Monolith
The oldest ones are the Monolith. The whole project goes inside the same repo. This is the simplest approach as it doesn't require any configuration.
The downside is that is not very scalable and doesn't encourage separation of concerns.
Let's say that a team now works on your project, each person adds a new dependency with different version and try to merge in. There will be merge conflict. How can we be sure what dependency version to use without having to test? Also bigger projects take more time to build/compile/process. Imagine having to wait an hour for the CI/CD to finish before being able to merge branches or make a deployment.
Monorepo
This approach has all the files on the same repo, but it tackles many of the problems that traditional monoliths have.
They help enforcing dependencies to always have the same version and store all node modules in a single location preventing duplication.
Also some monorepos, like Nx and Turborepo, "listen" for changes and only trigger actions (build/test) on this parts of the code.
The downside is that all the repos need to be released at the same time.
Polyrepo
In this scenario projects are stored in different repos.
It's easier to keep the components isolated.
It's easier to enforce authorization levels. Some devs might have access to the tools repo, but not to more sensitive repos.
It also allows the release to production at different times for different repos.
The downsides is if you want to make a change to multiple repos (code change, eslint, ...), you'll have to create a commit for each of them. And if you have repo dependencies (1 repo needs to be updated before you can update the other repo) then there could be bottlenecks.
Also if multiple repos need to use the same node modules, each one would have their own copy.
Micro-Frontend
It borrows the same concept of BE microservices, where FE Components live in different repos and are only "called"/used by the main code in an ad-hoc basis/when needed.
It can live inside a monorepo
Summary
To conclude, the strategy to use depends on the size and proximity of the code.
If it's a very small code base, monolith is the way to go.
If it's a big code with components that are related, then monorepo might be the best choice.
If it's a big code that parts of it are very different from the others, like BE and FE, or FE components for different platforms, then it's advantageous to use different repos or even micro-frontend.