Every Angular team hits this question eventually: our app is getting big, several teams touch it, builds are slow — should we split into micro frontends?
And almost every team asks it after reading a post about how Spotify or Zalando did it. What those posts don't say is that both companies had dozens of teams and deployment bottlenecks that were costing them real money.
I've built and maintained both setups on enterprise Angular projects — a monorepo with shared libraries, and a full Native Federation micro frontend system on a government platform. They solve different problems, and picking the wrong one costs you months.
Here's the honest way to decide.
The short answer
| Your situation | What you need |
|---|---|
| One team, growing codebase | Monorepo |
| 2–3 teams, one release cycle | Monorepo with library boundaries |
| 4+ teams, independent release cycles | Micro frontends |
| Teams blocked waiting on each other to deploy | Micro frontends |
| Different apps sharing a design system | Monorepo |
| Acquired product you can't rewrite | Micro frontends |
| Build times are slow | Neither — fix your build |
If your reason for wanting micro frontends is "our build is slow" or "our codebase is messy," micro frontends will make both worse. Keep reading to see why.
What a monorepo actually solves
A monorepo (Nx, Turborepo, or plain npm workspaces) gives you:
- One dependency tree. Every app runs the same Angular version. No version negotiation, ever.
- Enforced boundaries without runtime cost. Nx module boundary rules let you say "the billing lib may not import from admin" and fail the build if someone tries. You get architectural discipline with zero network requests.
- Atomic changes. Rename a shared component and update all 12 usages in one commit, one PR, one review.
- Cheap sharing. A shared UI library is just an import. No federation config, no version pinning strategy, no shared singleton contracts.
What it doesn't give you: independent deployment. Everything ships together.
For most teams, that's fine. If your whole product releases every two weeks anyway, shipping together isn't a constraint — it's just how you work.
What micro frontends actually solve
Micro frontends solve exactly one problem well: independent deployability.
That's it. Not code organization — a monorepo does that better. Not build speed — federation adds overhead. Not "cleaner architecture" — you can have clean architecture in a single app.
The one thing they give you that nothing else does: the billing team can ship a fix at 3pm on Tuesday without coordinating with four other teams, without a shared release train, and without anyone else's tests blocking their deploy.
If that scenario describes a real, recurring pain in your organization, micro frontends earn their cost. If it doesn't, you're about to pay a large bill for a problem you don't have.
The four-question test
Answer honestly:
1. Do separate teams need to deploy on separate schedules?
Not "would it be nice" — do you currently have teams blocked, waiting for someone else's release? If your whole org ships together every sprint, the answer is no.
2. Do you have the operational maturity for N pipelines?
Micro frontends mean N build pipelines, N deployments, N monitoring dashboards, N rollback procedures. If one CI pipeline is already fragile, five will be five times as fragile.
3. Can you commit to shared dependency contracts?
Every team must agree to upgrade Angular at the same time, or you get runtime version conflicts. This is an organizational agreement, not a technical one — and it's where most micro frontend adoptions quietly fall apart.
4. Is anyone accountable for the shell?
The shell app — routing, auth, shared state, remote loading — is a real product that needs a real owner. When it belongs to "everyone," it belongs to no one, and it rots.
Fewer than three yeses? Build a monorepo. You'll get most of the organizational benefit at a fraction of the operational cost.
The costs nobody puts in the blog posts
Having run this in production, the bills that arrive later:
Version drift is a runtime failure, not a build failure. In a monorepo, an incompatible dependency breaks your build — annoying, but caught immediately. In micro frontends, it breaks at runtime, in production, for whoever loads that remote. You now need a version governance process.
Auth gets harder than you expect. Token storage, refresh flow, logout across boundaries — if each remote handles its own, you get race conditions and tokens that survive logout. It has to live in the shell as a shared singleton, and every remote must agree to consume it and never manage it.
Every remote is a network dependency that can fail. If your shell calls loadRemoteModule() with no .catch(), one bad deploy takes down a route — or the whole shell. Nearly every tutorial omits this, because in local dev the remote always loads.
Debugging crosses boundaries. A bug that spans the shell and two remotes means three repos or three project folders, three sets of source maps, and three teams in the thread.
Onboarding gets slower. A new developer has to run the shell plus the remotes they touch, understand federation config, and learn which parts are shared. In a monorepo they run one command.
None of these are dealbreakers. They're just real, and they're why the answer should be "yes, we need independent deployment" and not "yes, this sounds modern."
The middle path most teams should take
Here's what I'd recommend to most Angular teams asking this question:
Start with a monorepo, structured as if you might split later.
- Separate your app into feature libraries with clear boundaries — enforce them with lint rules so violations fail CI
- Keep shared UI and utilities in their own libraries
- Route by feature namespace (
/billing/**,/admin/**) as if each were a remote - Own auth in one place, injected as a singleton
Do this, and if you later genuinely need independent deployment, extracting a feature into a remote is a contained refactor rather than a rewrite. And if you never need it, you still have a clean, boundaried codebase — with none of the runtime cost.
The teams that suffer most are the ones who jumped straight to micro frontends for a monorepo problem, then spent a year maintaining distributed infrastructure to ship one release train.
If you decided you do need micro frontends
Then the decisions that matter get made before the first remote is written: dependency contracts, auth ownership, routing namespaces, failure fallbacks, and deployment boundaries. Get those right and the architecture pays for itself. Get them wrong and you have a distributed monolith with extra network requests.
I wrote about the five most expensive of those decisions here: 5 Angular Micro Frontend Mistakes That Only Show Up in Production
Over to you
I'm curious about the split in practice: if your team adopted micro frontends, was independent deployment the actual reason — or did it become the justification after the decision?
I've seen both, and I'm genuinely interested in which is more common. Drop it in the comments.
I built NgMFE Starter Kit — a complete Angular 21 Micro-Frontend boilerplate with everything pre-configured:
⚡ Angular 21 + Native Federation
🔐 JWT Auth + Route Guards + Interceptors
📡 NgRx Signals Store
🌍 i18n (EN/FR/AR) + Arabic RTL
🌙 Dark/Light mode
🛡 Remote load-failure fallback with retry
🚀 CI/CD with GitHub Actions + Vercel
✅ 15 unit tests passing
🔴 Live Demo: https://ng-mfe-shell.vercel.app (login: admin/admin)
🛒 Get the kit: https://mhmoudashour.gumroad.com/l/hdditr?utm_source=devto&utm_medium=monorepo_article
📦 Or grab the free version — NgMFE Lite: https://mhmoudashour.gumroad.com/l/bqceke?utm_source=devto&utm_medium=monorepo_article
💼 Need it set up for your project? Hire me on Upwork
Top comments (0)