8. April 2026 By Milena Fluck and Andy Schmidt
Microfrontends in Monorepo: Maximum Decoupling with Minimal Redundancy
A few months ago, we faced a major challenge with a customer: the customer's front-end applications had been developed and maintained over many years by different teams in separate repositories.
Each team, sometimes different service providers, worked on its own front-end application. Different technologies, separate release cycles, separate build pipelines, different UI/UX approaches, varying degrees of accessibility support. What initially sounded like flexibility quickly led to redundancies, varying quality standards and increasing complexity in maintenance and integration. A consistent user experience was also not possible due to different UI frameworks and UI/UX approaches.
The customer wanted three key things:
- Reusability of code & components
- Independent and fast deployments
- Lower maintenance costs with clear architecture and coding standards
Our response was an architecture that combines microfrontends with a monorepo using Nx and import maps to achieve maximum decoupling with minimum redundancy.
Why microfrontends?
Similar to microservices, microfrontends are individual, clearly defined parts of an overall application that can be developed, tested and deployed independently.
Each team is responsible for its own area, can plan releases independently, and the effects of errors remain localised.
The whole thing works like a modular system of building blocks: each building block represents a feature or a technical component, whether it's a UI component, backend adapter or technical feature. The building blocks can be easily reused, recombined or exchanged. This allows you to flexibly configure a front-end application for each client, but also to quickly implement entire technical applications for completely new use cases.
Nx monorepo as a technical foundation
A monorepo based on the principle of Nx is not a contradiction to modularity – on the contrary: Nx offers a powerful build and orchestration tool as well as support for a quick start for large code bases and multiple teams.
It enables:
- shared libraries and utilities that can be used by all teams,
- intelligent dependency analysis and only affected builds & tests,
- uniform pipelines for quality assurance, testing and deployment.
This structure reduces maintenance effort: shared rules, shared toolchains, a shared repository, but still independent components.
Import maps – decoupling at runtime
A key issue with microfrontends is the question: How do we load the individual parts at runtime without coupling everything statically?
This is where import maps come into play. A browser technology that controls how modules are resolved in the browser. A shell interprets the import maps, loads and orchestrates the modules to create a frontend application that appears to be seamless.
With import maps, we define a mapping table, for example
<script type="importmap">
{
‘imports’: {
‘feature-a’: ‘/dist/feature-a/main.js’,
‘feature-b’: ‘/dist/feature-b/main.js’
}
}
</script>
This tells the browser where to find which modules at runtime without us having to hard-couple bundles. This allows us to:
- deploy individual microfrontends independently,
- dynamically import new versions,
- perform rollbacks quickly,
- and work without significant build overhead.
Import maps create a loose coupling between the shell and microfrontends through this separation.
Communication between microfrontends
Even with clear decoupling, the individual parts must still communicate with each other. Let's imagine, for example, that a microfrontend toggles between light and dark mode. All other microfrontends must also know this in order to behave correctly. Various patterns can be used for this:
- Query parameters for state transfers (route-based sharing, deep linking, etc.)
- Broadcast channels for event-based communication (cross-tab events such as logout, theme change, token refresh via the BroadcastChannel API)
- Shared state / shared services (central login status, user profile, feature flags, global API client, shared caching, central error handling)
These patterns allow communication to be structured cleanly without creating silos or unclear dependencies.
Advantages for customers and teams
The combination of microfrontends, Nx Monorepo and import maps brings many advantages:
For developers:
- Independent development & deployments
- Lower complexity
- Faster feedback loops
For the business:
- Higher resilience of the overall system: errors affect one module, not the entire front end, and errors in shared building blocks only need to be fixed once
- Fast and independent releases of individual features (time-to-market)
- Reduced redundancy in code and business
- A consistent user experience across all features and products
Infrastructure & maintenance:
- Centrally managed standards for quality, testing, UI
- Clear architecture rules and standards
- Efficient builds thanks to intelligent caching
Conclusion: Balance between decoupling and platform (common basis)
The combination of microfrontends and libraries in the Nx monorepo with import maps has proven to be an extremely successful approach in our project.
The use of a shared repository prevents redundant implementations, reduces integration effort, ensures consistent standards and greatly facilitates maintenance and governance. At the same time, the architecture allows each team to work autonomously, release independently and exchange individual features as needed – just like a modular system.
What initially seemed like a contradiction has proven to be the perfect balance between modularity and a shared structure: maximum decoupling with minimal redundancy – exactly what our customer was looking for.