Skip to main content

Microfrontends

Microfrontends are an architectural approach to building a web product from independently owned frontend parts. A composition layer brings those parts together into a user experience; each part may represent a business capability or a user-facing domain. The goal is to apply some of the organizational and delivery benefits of independently deployable services to the frontend.

This is an organizational and architectural boundary, not a requirement to use multiple frameworks, repositories, or deployment systems. A well-modularized frontend can provide clear ownership and boundaries without becoming a distributed system. Microfrontends are useful only when the autonomy they provide is worth the additional coordination and runtime or build complexity.

What the architecture changesโ€‹

In a conventional frontend, one application usually owns the page composition, shared dependencies, and release process. With microfrontends, those responsibilities are divided across multiple independently owned parts. A shell or another composition layer may own global navigation, routing, shared layout, and the integration contract, while domain teams own the experiences within their boundaries.

The parts can be composed at different stages:

  • Build-time composition combines independently developed parts before the application is delivered. It can keep runtime behavior simpler, but changes to a part generally need to be incorporated into a new application build.
  • Runtime composition loads parts as the application runs. It can allow teams to release separately, but makes availability, compatibility, loading performance, and failure handling runtime concerns.
  • Server-side composition assembles parts before sending a page to the browser. It can support server rendering and reduce some client-side coordination, but adds server-side integration and operational requirements.

These are broad approaches, not interchangeable products or a maturity ladder. The right choice depends on how independent releases need to be, the desired user experience, rendering requirements, and the team's operational capabilities. Some systems combine approaches.

Why teams consider microfrontendsโ€‹

Microfrontends can be useful when a product and its organization have grown beyond what one frontend team or release process can manage comfortably:

  • Independent ownership: Teams can own a coherent user-facing capability end to end, with explicit boundaries and responsibility for its quality.
  • Independent delivery: A team can release a change without waiting for every other frontend team, provided the integration contracts remain compatible.
  • Incremental modernization: Parts of an application can be replaced or moved gradually instead of requiring a coordinated rewrite.
  • Different domain needs: Teams can make local technology or delivery decisions where those differences have a concrete benefit and fit within shared product standards.
  • Organizational alignment: Frontend ownership can align more closely with domain or product teams, reducing handoffs for changes within a capability.

These benefits are conditional. Independent repositories or deployments do not automatically produce independent teams or faster delivery; shared contracts, release coordination, platform work, and cross-team dependencies can still be bottlenecks.

When they are a poor fitโ€‹

Prefer a single application with clear internal modules when:

  • The product is small, the team is small, or one team can coordinate releases effectively.
  • The application has a tightly integrated experience in which many screens, workflows, and UI elements change together.
  • The main motivation is to adopt a fashionable architecture, use different frameworks, or improve performance without evidence that the current structure is the cause of a problem.
  • Teams do not have the deployment automation, testing, monitoring, and ownership practices needed to operate independently.
  • The organization cannot agree on stable boundaries, shared interface contracts, or responsibility for the composition layer.
  • A strict performance, accessibility, or consistency budget would be difficult to enforce across independently delivered parts.

Do not split by page, component, or team name alone. A boundary that creates frequent cross-part changes or shared state is likely to add coordination rather than remove it. First consider whether a modular monolith, shared component library, or clearer team ownership would solve the actual problem with less operational overhead.

Costs and problems to plan forโ€‹

Microfrontends move complexity; they do not eliminate it. Teams should account for the following costs before choosing the architecture.

User experience and performanceโ€‹

Each independently delivered part can add JavaScript, network requests, loading work, and coordination at startup or during navigation. Shared libraries may be downloaded more than once, while aggressive sharing can introduce version constraints and hidden coupling. Runtime composition does not make a site faster by itself; measure the complete user experience, including initial load, navigation, interaction responsiveness, and failure states.

Independent teams can also produce inconsistent layouts, visual styles, interaction patterns, and accessibility behavior. A shared design system, clear ownership of global elements, and ongoing quality checks are needed. These standards should enable independent work rather than force every change through a central team.

Integration and change coordinationโ€‹

The parts still need to agree on routing, navigation, identity, permissions, data ownership, error handling, and how they communicate. Shared global state can make changes deceptively interdependent; unstructured events or browser globals can be just as difficult to reason about. Favor small, explicit contracts and keep cross-part communication limited to what the product requires.

Shared dependencies are another trade-off. Duplicating them may increase payload and create inconsistent behavior; sharing them may bind teams to compatible versions and coordinated upgrades. A technology choice that is technically possible is not necessarily worth the long-term support burden.

Reliability, security, and operationsโ€‹

Runtime composition introduces more failure points: a part may be unavailable, load slowly, or be incompatible with the host. The surrounding experience needs a defined response, such as a useful fallback that preserves other parts of the page. Teams need end-to-end observability that can identify which part, version, and integration boundary caused a user-facing problem.

Separate deployment is not, by itself, a security boundary. Frontend parts running in the same page generally share the page's browser execution context and should not be treated as mutually isolated. Treat remote code and its delivery pipeline as production supply-chain dependencies; define who can publish it, how changes are reviewed, and how versions can be rolled back. If strong isolation is required, choose and assess an isolation mechanism explicitly.

Development and testingโ€‹

Local development may require several applications, versions, and services to run together. A change that works in one team's environment may fail when combined with the host or another independently released part. Unit tests alone cannot verify composition, navigation, shared contracts, or the user's complete workflow.

Keep tests at multiple levels: each part's own behavior, compatibility at its integration boundaries, and representative end-to-end journeys using the assembled product. Test meaningful combinations of versions, loading failures, and rollbacks without trying to test every theoretical combination. Make ownership of test environments and release compatibility clear.

Questions to answer before adopting themโ€‹

  1. What concrete delivery or ownership problem cannot be solved adequately with modules and team agreements inside one application?
  2. What are the stable business or user-journey boundaries, and how often do changes cross them?
  3. Which team owns the shell, global navigation, design system, shared dependencies, and integration contracts?
  4. How will the parts be composed, versioned, observed, tested, and rolled back?
  5. What happens to the user experience when a part is slow, unavailable, or incompatible?
  6. How will the whole product maintain performance, accessibility, visual consistency, and security standards?
  7. Is the additional platform and coordination work sustainable for the teams that will operate it?

If these questions do not have practical answers, start with simpler boundaries and revisit the decision when the product or organization demonstrates a need for independent frontend delivery.

For related architectural decisions, see choosing a rendering architecture and design systems. Rendering architecture and microfrontend composition are related but separate choices: a product can use different rendering models without being divided into independently owned frontend applications.

Further readingโ€‹

  • Micro Frontends โ€” an overview of the pattern, its composition approaches, and organizational considerations.
  • Module Federation โ€” documentation for one Webpack mechanism for runtime sharing and composition; it is an implementation option, not a definition of microfrontends.
  • Web Vitals โ€” user-centered performance metrics useful for evaluating the impact of frontend composition.
  • Web Components โ€” browser standards for reusable custom elements, which may be used as part of a composition strategy but do not, on their own, provide independent ownership or deployment.