Back to articles
ArchitectureReact

Micro-Frontends: When They Help and When They Hurt

I shipped a micro-frontend platform that cut deployment time by 40% across five product modules. Here's the honest view of what you gain, what it costs, and when a monolith is the smarter call.

Yash Thakur
4 min read
Micro-Frontends: When They Help and When They Hurt

The short answer: micro-frontends help when independent teams are blocked by a shared release train — they're an organizational fix that lets each team build, test, and deploy on its own cadence (mine cut deployment time ~40% across five modules). They hurt when you have one team and one deploy cadence, where they buy all the cost of distributed systems and none of the benefit; in that case a well-modularized monolith is the smarter call.

Micro-frontends are the architecture everyone wants after they've felt the pain of a frontend monolith where one team's deploy blocks four others. I built one — a platform that let five product modules at Maxxton build, test, and deploy independently, which took our end-to-end deployment time down by about 40%. It was the right call there. It would have been the wrong call for most of the apps I've worked on since. The nuance is the whole story.

The problem they actually solve

Micro-frontends are an organizational solution wearing a technical costume. The real win isn't runtime — it's that Team A can ship on Tuesday without waiting for Team B's half-finished feature to be deploy-ready. If you have one team and one deploy cadence, you have no problem for micro-frontends to solve, and adopting them anyway buys you all of the cost and none of the benefit.

The honest litmus test: are independent teams blocked by a shared release train? If yes, read on. If no, build a well-modularized monolith and move on with your life.

The approaches, briefly

  • Build-time integration (packages): simplest, but a shared build means you haven't actually decoupled deploys. Fine as a first step, not a real micro-frontend.
  • Module Federation (Webpack 5 / Vite plugin): runtime integration, each app builds and deploys on its own, the shell loads remotes at runtime. This is what I used, and what most teams should reach for.
  • Runtime via iframes or web components: maximum isolation, maximum integration pain (shared auth, routing, styling all get harder). Reserve for genuinely independent or legacy-wrapping cases.

That shared: { singleton: true } block is not optional decoration — it's what stops you shipping three copies of React and getting the dreaded "invalid hook call" when two Reacts collide.

The costs nobody puts on the slide

Shared dependencies become a treaty. Every team now negotiates React, your design system, and your auth library versions. A major React upgrade is a cross-team project, not a PR. The singleton/requiredVersion config above is you writing that treaty down.

Consistency drifts. Five independently-deployed apps will drift in spacing, button styles, and loading patterns unless a shared design system is enforced — which means the design system itself becomes a critical, versioned, independently-deployed dependency with all the same coordination overhead.

Debugging crosses boundaries. A bug that spans the shell and two remotes is harder to reproduce, harder to trace, and the stack trace points into a bundle built by another team on another schedule. Observability and good error boundaries stop being nice-to-haves.

What I'd tell my past self

Start as a modular monolith with hard internal boundaries — clean module seams, no cross-imports between features, a shared design system as an internal package. If and when the organizational pain of a shared release train becomes real, those seams are exactly where you split, and Module Federation becomes a refactor rather than a rewrite. Adopt micro-frontends to solve a team-coordination problem you can actually point to — never because the architecture diagram looks impressive. The 40% I saved was real, but it was paying down a cost we'd already incurred, not a prize for using a fancy pattern.

Written by Yash Thakur

Senior React Developer · 8+ years building for the web

More articles

Keep reading