Article Guide
Architect20 min readJune 12, 2026

Micro Frontends System Design: Design an E-commerce Platform

Design a production-grade e-commerce frontend using micro frontends, including shell architecture, domain remotes, routing, auth, cart state, checkout reliability, deployment, rollback, observability, and interview tradeoffs.

Tags:
Micro FrontendsSystem DesignE-commerceFrontend ArchitectureInterview Prep

Designing a micro frontend system for an e-commerce platform is one of the best ways to understand frontend architecture at senior and architect level.

It combines almost every important frontend system design topic:

textEditor
Routing
Authentication
Cart state
Checkout reliability
Runtime composition
Shared design system
Independent deployment
Rollback
Observability
Performance
Team ownership

This article walks through how to design a production-grade e-commerce frontend using micro frontends.

The goal is not only to build the system, but also to explain it confidently in interviews.

1. Problem Statement

We need to design the frontend architecture for a large e-commerce platform.

The platform has multiple product areas:

textEditor
Home
Catalog
Search
Product Details
Cart
Checkout
Orders
Profile
Marketing
Recommendations

Multiple teams work on the frontend: Catalog Team, Search Team, Cart Team, Checkout Team, Orders Team, Profile Team, Marketing Team, Platform Team, and Design System Team.

Currently, all teams work inside one large frontend monolith. This creates delivery and ownership problems.

2. Existing Monolith Problem

The current architecture splits directories internally under a single codebase structure:

textEditor
frontend-monolith
├── home
├── catalog
├── search
├── product-details
├── cart
├── checkout
├── orders
├── profile
├── marketing
├── shared
└── app-shell

At first, this is simple. But as the product and teams grow, issues appear.

ProblemImpact
Many teams in one repoMerge conflicts and coordination overhead
One shared buildSlow CI/CD pipeline
One release cycleTeams block each other
Shared dependencies everywhereUpgrade risk
Unclear ownershipBugs move between teams
Large bundlePerformance degradation
Risky checkout changesBusiness-critical flow can break
Hard migrationNew architecture is difficult to introduce

A frontend monolith is not always bad. But when team scale and release independence become major bottlenecks, micro frontends become a possible solution.

3. System Design Goal

The goal is to split the e-commerce frontend into independently owned domain apps while keeping one seamless user experience.

We want:

  • Independent team ownership
  • Independent deployment
  • Clear domain boundaries
  • Shared UI consistency
  • Safe routing
  • Reliable checkout
  • Minimal cross-app coupling
  • Rollback support
  • Production observability
  • Good performance

We do not want:

  • A distributed mess
  • A giant global shared store
  • Every page as a separate micro frontend
  • A shell app full of business logic
  • Uncontrolled dependency versions
  • Runtime failures without fallback

Independent teams, independent deployment, shared user experience.

4. High-Level Architecture

Recommended architecture layout diagram:

architecture diagram
                    ┌────────────────────────┐
                  │        Browser          │
                  └───────────┬────────────┘
                              │
                              ▼
                  ┌────────────────────────┐
                  │        Shell App        │
                  │ Layout | Auth | Nav     │
                  │ Routing | Remote Loader │
                  └───────────┬────────────┘
                              │
      ┌───────────────────────┼───────────────────────┐
      │                       │                       │
      ▼                       ▼                       ▼
┌───────────────┐       ┌───────────────┐       ┌───────────────┐
│ Catalog Remote│       │ Cart Remote   │       │ Checkout Remote│
│ Catalog Team  │       │ Cart Team     │       │ Checkout Team  │
└───────┬───────┘       └───────┬───────┘       └───────┬───────┘
      │                       │                       │
      ▼                       ▼                       ▼
┌───────────────┐       ┌───────────────┐       ┌───────────────┐
│ Catalog API   │       │ Cart API      │       │ Payment API   │
└───────────────┘       └───────────────┘       └───────────────┘

A more complete system splits into several independent modules loaded by the Shell App:

textEditor
Shell App
├── Home Remote
├── Catalog Remote
├── Search Remote
├── Product Details Remote
├── Cart Remote
├── Checkout Remote
├── Orders Remote
├── Profile Remote
├── Marketing Remote
└── Recommendations Remote

5. Domain Boundary Design

Choosing good boundaries is the most important decision. A good micro frontend boundary should have clear business ownership, independent release need, limited communication with other domains, clear route ownership, clear API ownership, and clear team ownership.

RemoteOwned ByResponsibility
Home RemoteMarketing/Home TeamHomepage, hero sections, campaign blocks
Catalog RemoteCatalog TeamCategory pages, listing, filters, sorting
Search RemoteSearch TeamSearch results, suggestions, search filters
Product Details RemoteProduct TeamPDP, product media, product info
Cart RemoteCart TeamCart page, cart drawer, quantity updates
Checkout RemoteCheckout TeamAddress, delivery, payment, order placement
Orders RemoteOrders TeamOrder history, order details, reorder
Profile RemoteProfile TeamAccount, address book, preferences
Marketing RemoteMarketing TeamCampaign banners, landing pages
Recommendations RemotePersonalization TeamSimilar products, recommendations widgets

Avoid overly tiny boundaries. A bad split creates too much runtime overhead and coordination (e.g. creating separate remotes for Button, Header, Price, Image, and Filter). A good split uses larger vertical blocks (e.g. Catalog Remote, Cart Remote, Checkout Remote, and Profile Remote).

6. Shell App Responsibilities

The shell is the host/container application. It should own platform-level concerns:

  • Global layout
  • Header and footer frame
  • Top-level routing
  • Authentication bootstrap
  • Remote loading
  • Global navigation
  • Feature flag bootstrap
  • Error boundaries
  • Fallback UI
  • Global analytics initialization
  • Remote version awareness

Example layout structure:

textEditor
Shell App
├── App Layout
├── Header
├── Footer
├── Auth Guard
├── Route Config
├── Remote Loader
├── Error Boundary Wrapper
├── Feature Flag Provider
└── Analytics Bootstrap

The shell should not own domain business logic. Bad shell responsibilities include: cart calculations, product filtering logic, payment validation, order history rules, or search rankings.

The shell should coordinate composition, not become a business-logic dumping ground.

7. Remote App Responsibilities

Each remote owns its own domain experience.

Example configurations:

textEditor
Catalog Remote owns: Category page, PLP, filters, sorting, pagination, card rendering, and Catalog APIs.
Cart Remote owns: Cart page, cart drawer, cart summary, updates, promo code UI, and Cart APIs.
Checkout Remote owns: Address forms, delivery choice, payment steps, order reviews, order placement, and Payment APIs.

Each remote should be independently testable and deployable.

8. Routing Design

A simple routing model defines:

Shell owns top-level routes. Remotes own nested routes inside their boundaries.

Example route paths:

textEditor
/                         → Home Remote
/categories/:categorySlug → Catalog Remote
/search                   → Search Remote
/product/:productId       → Product Details Remote
/cart                     → Cart Remote
/checkout                 → Checkout Remote
/orders                   → Orders Remote
/profile                  → Profile Remote

URLs must be shareable, bookmarkable, and refresh-safe. Avoid bad designs where page works only when navigated from the home page. In a good design, opening /categories/shoes?sort=price directly loads the correct remote entries cleanly.

9. Runtime Loading Sequence

When a user visits /cart, the shell app loads first, checks route configurations, fetches the remote Entry manifest, downloads the chunks, mounts the Cart component inside the shell layout container, and triggers Cart APIs to render the UI.

If the remote fails to load at runtime, the Shell catches the error, logs the load failure to telemetry, and displays a graceful fallback UI placeholder, keeping the navigation, header, and footer active.

10. Module Federation Design

Using Module Federation, host configures remote CDN endpoints, e.g. mapping catalogApp to https://cdn.company.com/catalog/remoteEntry.js.

Exposed assets are configured cleanly: catalogApp exposes ./CatalogPage, ./ProductList, and ./CategoryRouteConfig, while cartApp exposes ./CartPage, ./CartDrawer, and ./CartBadgeProvider.

Expose public contracts, not internal implementation details.

11. Shared Dependency Strategy

Shared dependencies must be controlled carefully.

DependencyStrategy
ReactSingleton
React DOMSingleton
Design systemShared with strict versioning
Analytics SDKShared or initialized by shell
Auth SDKUsually shell-owned/shared carefully
RouterBe careful; shell owns top-level routing
API clientsDomain-owned
Business logicDomain-owned
Global storeAvoid unless strongly justified

React must be a singleton because duplicate React bundles in the browser run in separate instances, causing hooks and context state scopes to fail.

12. Design System Strategy

A large e-commerce platform must look like one product. To maintain consistency, utilize a shared design system that distributes tokens, spacing, colors, and reusable stateless UI components (like buttons, modals, cards, and forms).

Each remote imports and references these tokens. Without strict design system governance, teams will introduce divergent styling rules, broken layout behaviors, and inconsistent loading feedback, destroying the cohesive UX.

13. Cart State Design

Sharing a giant global Redux store across remotes is an anti-pattern because it tightly couples the codebases. A better approach is making the Cart API the source of truth:

textEditor
Product Details Remote
    │
    │ add item (Cart API call)
    ▼
Cart API
    │
    │ returns updated count
    ▼
Cart Updated Event (explicit event bus payload)
    │
    ▼
Shell Header updates cart count badge

Business-critical state like cart should be backend-first, not hidden inside a shared frontend store.

14. Checkout Reliability Design

As a critical conversion path, the checkout flow requires maximum resilience. Use stable version pinning for checkout remotes rather than always pointing to latest builds. Implement dynamic preloading of the checkout bundle as soon as the user interacts with the cart, wrapping checkout components with strict local error boundaries and form cache recovery layers.

15. Authentication and Authorization

The Shell bootstraps login sessions, monitors token refreshes, and exposes identity context. Remotes check user roles locally to enable or disable features (e.g. showing shipping updates). Always remember:

Frontend authorization improves UX, but backend APIs must enforce real authorization. Never trust client-side checks only.

16. Communication Between Remotes

Recommended communication path hierarchy is: URL state (query params for filters), Backend APIs (cart quantities), Custom DOM Events (badge updates), and Shell auth context (session tokens).

If two micro frontends communicate constantly, the boundary is probably wrong.

17. Performance Design

Performance budget risks and solutions in composed architectures:

Performance RiskArchitectural Solution
Duplicate React bundlesSingleton shared dependency settings
Loading every remote upfrontRoute-level dynamic lazy loading
Checkout slow transitionPreload checkout remote after cart activity
Large design system bundleTree-shaking and token-based exports
Runtime load waterfallsPrefetch critical remote chunks in advance
Layout shiftsReserve container spaces with skeleton screens

18. Failure Isolation

Wrap remotes inside independent React error boundaries at the composition level. If the recommendations widget crashes, display a blank frame or minor fallback element without breaking the page's core header, navigation, and purchase buttons.

19. Deployment Strategy

Each remote repository contains its own build, test, and release configuration, producing versioned bundle files pushed to a CDN. In CI checkpoints, run automated contract tests and bundle analyzers before promoting a build.

20. Remote Manifest Strategy

Deployments should update a central JSON version manifest file on a CDN instead of referencing dynamic CDN pointers directly. This ensures that the shell loads specific, validated, and promote-tested bundle URLs for each route, allowing for immediate version locks and canary releases.

21. Rollback Strategy

When a bug is discovered in a remote deployment, update the CDN manifest to point back to the previous version's build path and purge the CDN caching headers. The shell will instantly load the older, stable remote bundle without rebuilding the shell itself.

A micro frontend architecture is not production-ready unless each remote can be rolled back safely.

22. Testing Strategy

To avoid flaky global E2E scripts, combine unit testing inside remotes with strict contract checks at deployment gates, asserting that exposed module interfaces, event formats, routing paths, and shared package versions remain compatible.

23. Observability Design

Logging systems must tag errors with the owning remote name and commit version. Inject a global session correlation ID into all server query headers, and track remote download latencies using browser performance logging APIs.

24. Security Design

Enforce Content Security Policies (CSP) to restrict scripts loading to verified CDN origins, apply strict CORS validation rules, and avoid sharing authorization tokens or user keys via DOM custom events.

25. Team Ownership Model

Establish clear boundaries: a Platform Team owns the Shell and remote loaders; a Design System Team owns UI components; and separate Product Teams own respective remotes (Catalog, Cart, Checkout, Profile), managing their own tests, builds, and on-call logs.

26. Governance Model

Autonomy does not mean complete isolation. Establish platform standards for dependency locking, bundle size budgets, telemetry tracking, and event naming formats, while leaving teams free to choose internal folder structures and compile patterns.

The goal is not unlimited freedom. The goal is safe autonomy.

27. Common Tradeoffs

Decision OptionArchitectural BenefitArchitectural Drawback
Runtime compositionMaximum deployment decouplingHigher runtime loading failure risk
Shared design system libraryConsistent visual identityCoordination overhead during upgrades
Shell-controlled routingPredictable global navigationShell must maintain route domain map
Backend-driven cart stateReliable single source of truthHigh latency on poor networks
CDN versioned manifestsSafe atomic rollback operationsAdded deployment orchestration layer

28. When to Reject Micro Frontends

Reject this architecture if the engineering team is small (under 15 devs), the application is simple, or a unified release train is sufficient. In these scenarios, the tooling and coordination overhead will drag down velocity. Recommend a modular monolith instead.

29. Interview-Ready Final Answer

To pitch this design successfully:

I would design the platform using a shell app and multiple domain-owned remotes. The shell would own global layout, top-level routing, authentication bootstrap, remote loading, feature flag initialization, and error boundaries. The remotes would be split by business domains such as catalog, search, product details, cart, checkout, orders, and profile. Each remote would have its own team, repository or package boundary, CI/CD pipeline, test suite, deployment lifecycle, and monitoring dashboard. For communication, I would avoid a giant shared global store. I would use URL state for filters and search, backend APIs as the source of truth for cart and checkout, and small explicit events for cross-app notifications like cart count updates. The key tradeoff is that micro frontends improve team autonomy and independent releases, but they add complexity in runtime loading, dependency sharing, testing, observability, and governance. I would only choose this architecture when the team structure and release model justify the complexity.

30. Final Architecture Checklist

  • Are domain boundaries clear?
  • Does each remote have an owning team?
  • Does each remote have independent CI/CD?
  • Does the shell avoid domain business logic?
  • Is routing ownership clearly defined?
  • Does deep linking work?
  • Is cart state backend-first?
  • Is checkout treated as a critical flow?
  • Are React and React DOM shared safely?
  • Is there a shared design system?
  • Are remotes wrapped with error boundaries?
  • Is fallback UI available?
  • Are contract tests in place?
  • Is rollback per remote possible?
  • Is observability per remote available?
  • Are performance budgets defined?
  • Is the architecture simpler than the problem it solves?

31. Summary

Designing an e-commerce platform with micro frontends is first and foremost an organizational scaling exercise. Autonomy is only safe when governance, contracts, resilient boundaries, and automated rollback configurations are designed properly from day one.

Micro frontends are worth it when frontend team scale and release independence matter more than architectural simplicity.

References

  • Micro Frontends — Martin Fowler (https://martinfowler.com/articles/micro-frontends.html)
  • Micro Frontends (https://micro-frontends.org)
  • webpack Module Federation Documentation (https://webpack.js.org/concepts/module-federation/)
  • AWS Prescriptive Guidance: Micro-frontends (https://docs.aws.amazon.com/prescriptive-guidance/latest/micro-frontends-aws/introduction.html)
  • Module Federation Official Site (https://module-federation.io)