We spent two weeks setting up Module Federation before writing a single feature. It was the right call.
The theory is clean: each app is independent, shares dependencies at runtime, and deploys on its own. In practice we were integrating two separate React apps into a single shell, and both needed to share auth state and some UI components in real time. The setup was more involved than the docs make it sound.
Shared dependencies become a negotiation
Both apps need React. If they sit on different versions, you either coordinate a pinned version across both teams or you live with duplicate instances loading at runtime. We pinned. That meant syncing version upgrades between two codebases from then on, which is a cost you sign up for whether you notice it or not.
Auth state across module boundaries is a design decision, not a detail
We had specific security requirements around how tokens were stored and passed between apps. That had to be decided up front. Solving it mid-sprint, when features are already blocked on it, is the kind of refactor that quietly kills a week of momentum.
Local dev with several apps running at once has its own learning curve
Port conflicts, startup order, shared environment variables. A single dev script that boots everything in the right sequence removed a surprising amount of daily friction. Small thing, big payoff.
What I'd pass on
If you're starting with Module Federation: get the shared dependency list right before any feature code, and solve auth across app boundaries before you need it. The two weeks felt slow while we were in them. They paid for themselves the moment we started shipping features in parallel without stepping on each other.