Decision: use a modular monolith by default. Move to microfrontends only when independent frontend deployment is worth the platform tax.
The Default Fighter: Modular Monolith
A modular monolith keeps one app, one routing model, and one local setup while preserving domain boundaries in the code. It is the heavy hitter when delivery speed, simplicity, and product consistency matter more than separate deployments.
- Speed: teams spend less time maintaining integration infrastructure while the product is still changing.
- UX consistency: one shell, shared state, and one design system leave fewer seams for users to trip over.
- Debugging: failures usually remain inside one runtime and one call stack instead of crossing remote boundaries.
The Specialist: Microfrontends
Microfrontends become useful when several mature teams own stable domains and genuinely need to ship them independently. They trade simplicity for autonomy; that trade is worthwhile only when the shared frontend release train has become a measurable bottleneck.
- Independent deploys: domain teams can ship without waiting for a crowded central release.
- End-to-end ownership: a team can own its UI, runtime, contracts, and delivery path.
- Incremental migration: old and new stacks can coexist behind a shell when a full rewrite would be too risky.
Fight Summary
The Knockout Rule
Do not split because the codebase feels big. Messy components, slow CI, unclear ownership, and framework arguments are cleanup and platform problems first. Microfrontends can expose those problems faster; they rarely make them disappear.
Split only after domains are stable, teams own product areas end to end, and someone is ready to own the shell, contracts, observability, and integration tests.


