Microfrontends Under Real-World Conditions
A few years ago, when the hype around microfrontends started gathering momentum, one phrase caught my attention:
TRUE independent teams
TRUE really was written entirely in uppercase.
It sounded suspiciously like marketing. Still, the phrase stayed with me. Because genuine team independence is a powerful architectural promise: a team understands its system, changes it, tests it, releases it, and operates it without having to wait for the rest of the platform at every step.
I started looking more closely at microfrontends and the ideas behind them. Along the way, I read a lot from people such as Manfred Steyer and Rainer Hahnekamp. The deeper I went into the subject, the less interesting the question of how to load the first remote became.
What happened afterwards was much more interesting.
Not Another Getting Started Guide
Section titled “Not Another Getting Started Guide”This series is not a tutorial along the lines of:
Here is how to build a host and three remotes.
Anyone looking to set up microfrontends or Module Federation with Nx can find an official guide in the Nx documentation.
The technical initialization is the comparatively easy part. Generators and existing integrations take care of many details that once had to be configured manually.
One recommendation from experience: do not rush into writing your own solution for this.
A custom configuration can make sense. It should solve a problem that actually exists. Otherwise, a handful of supposedly simple settings can turn remarkably quickly into a small platform that now also needs to be versioned, tested, and understood.
This series therefore does not begin with the first successful build.
It begins where the host is running and the simple slides stop.
Why This Series Exists
Section titled “Why This Series Exists”Microfrontends are often explained through their technical shape: host, remotes, Module Federation, runtime loading, separate builds.
That describes the mechanism. It does not answer the architectural question.
Under real-world conditions, other questions matter more: Who is allowed to change what? Which boundaries are actually independent? Who owns data, URLs, UI, and business processes? What happens when a remote fails? How can different versions run in parallel? How can a release be validated without rebuilding the entire product every time? And what is the gained autonomy actually worth once the additional infrastructure and coordination are included?
It quickly becomes apparent that many supposedly technical problems are really ownership problems.
A remote can be independently deployable and still have to wait for the shell team. Two teams can own separate repositories and still only be able to release together. A system can contain five remotes and remain an organizational monolith.
The architecture is distributed. The dependencies have simply acquired new addresses.
What the Following Articles Cover
Section titled “What the Following Articles Cover”The series therefore approaches microfrontends not through a reference diagram, but through the decisions that eventually have to be made in a real product.
It starts with the boundaries themselves: What problem is distribution supposed to solve? How large can a microfrontend become? When is a remote a real domain capability—and when is it merely a component library with a more expensive delivery mechanism?
Then integration becomes less comfortable. Remotes have to coexist while knowing as little about one another as possible. Frameworks and framework versions may diverge. The URL still needs an owner, the UI still needs to feel like one product, and shared technical capabilities must not quietly turn into the next form of domain coupling.
By the time authentication, failures, and testing enter the picture, the architecture diagram is no longer enough. An independent frontend also has to behave sensibly when other parts are unavailable. It needs to be developed and validated independently without recreating the entire surrounding platform.
And eventually, the system reaches production.
Then the discussion moves to immutable artifacts, product compositions, parallel versions, controlled activation, rollbacks, observability, and the deceptively simple support question:
Which application was this user actually seeing?
The final perspective is economic and organizational. Repository boundaries, platform teams, additional infrastructure, and independent releases all have a cost. Migration is therefore not an end in itself—and a good microfrontend strategy also needs an answer to the question of when to stop decomposing.
Independence Under Real-World Conditions
Section titled “Independence Under Real-World Conditions”The same idea runs through all of these questions:
A frontend does not become independent simply because its code lives in its own remote. What matters is whether teams can understand, change, test, release, and operate their systems independently.
The answer does not always have to be a microfrontend.
Sometimes a shared abstraction makes sense. Sometimes duplication is cheaper. Sometimes a modular monolith remains the better architecture. And sometimes the additional autonomy costs more than it will ever return to the product.
Microfrontends are neither inherently superior nor inherently wrong.
They are an architectural decision with consequences.
This series is about those consequences.