There is a version of the microfrontend pitch that is true: independent teams, independent deploys, no merge queue from hell. There is another version, the one that gets you a standing ovation at a conference and a 200ms regression in production. This is a story about the second one, told from inside a banking platform that adopted microfrontends for all the right reasons and paid for it in all the places nobody was looking.
- 01 Microfrontends move complexity from build time to runtime — where it is harder to test and audit.
- 02 In regulated finance, “independent deploys” collide with “one consistent disclosure” requirements.
- 03 Shared state (auth, feature flags, the design system) becomes a distributed-systems problem in the browser.
- 04 We kept the team autonomy and dropped the runtime composition. The org problem was never a code problem.
What we were actually trying to fix
Eight teams, one trading dashboard, one repository, one release train. The release train was the enemy: a risk change and a cosmetic change shipped on the same cadence because they shared a deploy. Microfrontends looked like the cure — let each team own a tile of the dashboard and ship it independently.
What we got instead
Performance: the composition tax
Each independently-deployed tile shipped its own copy of the framework runtime until we wrestled it into a shared dependency — at which point “independent” quietly became “coordinated”, which was the thing we were trying to avoid.
Governance: who owns the disclosure?
This is the finance-specific knife. A regulated product must present consistent disclosures, consistent rounding, consistent timestamps. With one codebase that is a code review. With eight independently-deployed tiles it is a distributed agreement problem — and there was no protocol for it.
// Tile A and Tile B both display a balance.// They fetch from different services, deployed at different times,// formatted by different (independently-versioned) utils.const a = formatCurrency(balanceFromLedger); // shipped Tuesdayconst b = formatCurrency(balanceFromCache); // shipped last month// Are these guaranteed to agree to the cent, today, in prod?// In a microfrontend world, the honest answer was "we hope so".Shared state: a tiny distributed system in the DOM
Auth tokens, feature flags, and the theme all had to be shared across tiles that
could not import each other. We ended up with an event bus on window, which is
to say we rebuilt service-to-service messaging inside a single browser tab,
without the observability we would demand of any backend.
The resolution
We kept the org win and dropped the runtime mechanism. Each team still owns its slice and ships on its own branch protections, but we compose at build time into a single artefact. Deploys are independent up to the integration build, which runs the cross-tile consistency checks that regulation actually requires.
Autonomy was the goal. Runtime composition was just one — expensive — way to get it.