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.
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:
Routing
Authentication
Cart state
Checkout reliability
Runtime composition
Shared design system
Independent deployment
Rollback
Observability
Performance
Team ownershipThis 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:
Home
Catalog
Search
Product Details
Cart
Checkout
Orders
Profile
Marketing
RecommendationsMultiple 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:
frontend-monolith
├── home
├── catalog
├── search
├── product-details
├── cart
├── checkout
├── orders
├── profile
├── marketing
├── shared
└── app-shellAt first, this is simple. But as the product and teams grow, issues appear.
| Problem | Impact |
|---|---|
| Many teams in one repo | Merge conflicts and coordination overhead |
| One shared build | Slow CI/CD pipeline |
| One release cycle | Teams block each other |
| Shared dependencies everywhere | Upgrade risk |
| Unclear ownership | Bugs move between teams |
| Large bundle | Performance degradation |
| Risky checkout changes | Business-critical flow can break |
| Hard migration | New 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:
┌────────────────────────┐
│ 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:
Shell App
├── Home Remote
├── Catalog Remote
├── Search Remote
├── Product Details Remote
├── Cart Remote
├── Checkout Remote
├── Orders Remote
├── Profile Remote
├── Marketing Remote
└── Recommendations Remote5. 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.
| Remote | Owned By | Responsibility |
|---|---|---|
| Home Remote | Marketing/Home Team | Homepage, hero sections, campaign blocks |
| Catalog Remote | Catalog Team | Category pages, listing, filters, sorting |
| Search Remote | Search Team | Search results, suggestions, search filters |
| Product Details Remote | Product Team | PDP, product media, product info |
| Cart Remote | Cart Team | Cart page, cart drawer, quantity updates |
| Checkout Remote | Checkout Team | Address, delivery, payment, order placement |
| Orders Remote | Orders Team | Order history, order details, reorder |
| Profile Remote | Profile Team | Account, address book, preferences |
| Marketing Remote | Marketing Team | Campaign banners, landing pages |
| Recommendations Remote | Personalization Team | Similar 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:
Shell App
├── App Layout
├── Header
├── Footer
├── Auth Guard
├── Route Config
├── Remote Loader
├── Error Boundary Wrapper
├── Feature Flag Provider
└── Analytics BootstrapThe 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:
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:
/ → 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 RemoteURLs 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.
| Dependency | Strategy |
|---|---|
| React | Singleton |
| React DOM | Singleton |
| Design system | Shared with strict versioning |
| Analytics SDK | Shared or initialized by shell |
| Auth SDK | Usually shell-owned/shared carefully |
| Router | Be careful; shell owns top-level routing |
| API clients | Domain-owned |
| Business logic | Domain-owned |
| Global store | Avoid 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:
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 badgeBusiness-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 Risk | Architectural Solution |
|---|---|
| Duplicate React bundles | Singleton shared dependency settings |
| Loading every remote upfront | Route-level dynamic lazy loading |
| Checkout slow transition | Preload checkout remote after cart activity |
| Large design system bundle | Tree-shaking and token-based exports |
| Runtime load waterfalls | Prefetch critical remote chunks in advance |
| Layout shifts | Reserve 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 Option | Architectural Benefit | Architectural Drawback |
|---|---|---|
| Runtime composition | Maximum deployment decoupling | Higher runtime loading failure risk |
| Shared design system library | Consistent visual identity | Coordination overhead during upgrades |
| Shell-controlled routing | Predictable global navigation | Shell must maintain route domain map |
| Backend-driven cart state | Reliable single source of truth | High latency on poor networks |
| CDN versioned manifests | Safe atomic rollback operations | Added 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)