Simpro Knowledge Base

Micro Frontends And Monorepos

Micro Frontends And Monorepos visual map

Purpose

This page helps Simpro decide when to use micro frontends, when to use a monorepo, and when to keep things simpler.

Micro frontends and monorepos are powerful patterns, but they are not automatic upgrades. Used well, they help teams move independently while sharing standards. Used badly, they turn one application into a distributed argument with build scripts.

The Core Idea

A monorepo is about managing many projects in one repository with shared tooling, dependency visibility, reusable libraries, and consistent CI.

A micro frontend is about composing independently owned frontend applications or features into one user experience.

They solve different problems:

Pattern Solves Does Not Automatically Solve
Monorepo Shared code, consistent tooling, atomic changes, dependency graph visibility Poor ownership, weak architecture, unclear boundaries
Micro frontend Independent frontend delivery by multiple teams Bad UX consistency, duplicated dependencies, unclear domain ownership

The best version is usually: clear product domains, shared design system, strong platform standards, visible ownership, and automation that makes the right thing easy.

When A Monorepo Helps

Use a monorepo when:

  • Multiple apps share common UI components, API clients, domain libraries, or platform tooling.
  • Teams need atomic changes across app and library boundaries.
  • CI can run affected builds/tests instead of rebuilding everything.
  • You want consistent linting, formatting, testing, dependency policy, and release workflows.
  • You need a visible project graph to understand impact.

Avoid a monorepo when:

  • Teams have completely unrelated products and release models.
  • The repository would become a dumping ground without ownership rules.
  • Build times are not controlled with caching and affected execution.
  • Shared code becomes a shortcut for tight coupling.

Monorepo Good Practices

Organize By Domain And Capability

Prefer folders that reflect product and platform boundaries:

apps/
  customer-portal/
  admin-console/
libs/
  ui/
  auth/
  billing/
  shared-api-client/
  testing/
tools/
docs/

Do not create a giant common area where all clarity goes to retire.

Enforce Boundaries

Use tooling rules so a feature module cannot import anything it wants. For example:

  • UI library can be imported by apps.
  • Domain libraries can import lower-level utilities.
  • Shared utilities should not import product features.
  • Experimental apps should not become dependencies of stable product apps.

Build Only What Changed

Large monorepos work because tooling understands the dependency graph. A good setup should support:

  • Affected build/test/lint.
  • Local and remote caching.
  • Parallel execution.
  • Clear ownership and code owners.
  • Automated dependency updates.
  • Release grouping where appropriate.

Keep Shared Libraries Honest

Shared libraries should be treated like products:

  • Clear owner.
  • Clear API.
  • Versioning or change discipline.
  • Tests.
  • Documentation.
  • Migration notes for breaking changes.

Tool Choices

Tool Good Fit
Nx Enterprise monorepos, dependency graph, affected commands, many frameworks, boundary rules
Turborepo JavaScript/TypeScript monorepos with fast task running and caching
pnpm workspaces Lightweight package workspace management
npm/yarn workspaces Standard workspace support for simpler setups

Simpro guidance:

  • Use Nx when we need strong governance, project graph, multiple apps/libs, and enforceable boundaries.
  • Use Turborepo when the stack is mostly JavaScript/TypeScript and the main problem is fast task orchestration.
  • Use plain workspaces when the repo is small and does not yet need heavier structure.

When Micro Frontends Help

Use micro frontends when:

  • Multiple teams own different product domains inside one larger experience.
  • Teams need independent deployability.
  • The application is large enough that one frontend codebase slows teams down.
  • Domain boundaries are clear.
  • UX/design-system governance is strong.
  • Observability and testing can cover the composed experience.

Avoid micro frontends when:

  • There is only one small frontend team.
  • The real problem is poor component architecture.
  • The user experience would become inconsistent.
  • Shared state and routing are unclear.
  • Each team would ship its own version of every dependency.

The humorous rule: do not use micro frontends to avoid talking to another team. The browser will not become your marriage counselor.

Micro Frontend Composition Options

Approach Use When Watch Out For
Module Federation Runtime composition and independent frontend deployment Versioning, shared dependencies, debugging
single-spa Multiple frameworks or apps composed into one shell Routing, lifecycle complexity
Web Components Framework-neutral components Design-system maturity and browser constraints
Build-time composition Simpler integration with shared packages Less independent deployment
iframe Strong isolation needed UX, accessibility, communication, performance

Start with modular frontend architecture inside one app or monorepo. Move to micro frontends only when team autonomy, deployability, and product-domain scale justify the complexity.

Recommended maturity path:

  1. Shared design system and UI library.
  2. Domain-based frontend modules.
  3. Monorepo with affected builds and boundaries.
  4. Independent app shells only where product domains need autonomy.
  5. Micro frontend composition for mature, separately owned domains.

Decision Checklist

Before adopting micro frontends, answer:

  • What product domains will own which frontend areas?
  • Who owns the shell, routing, authentication, and layout?
  • How will shared design-system changes be rolled out?
  • How will we prevent duplicate dependencies and performance regressions?
  • How will we test the composed experience?
  • Can each team deploy independently without breaking another team?
  • What observability tells us which micro frontend caused an error?

Before adopting a monorepo, answer:

  • What projects belong together?
  • What code should be shared?
  • What imports should be forbidden?
  • How will CI avoid running everything?
  • Who owns shared libraries?
  • How will dependency updates be controlled?

Team Reference Guide

Guidelines For Teams

  • Prefer modularity before distribution.
  • Use monorepos to improve visibility and automation, not to erase ownership.
  • Use micro frontends for domain autonomy, not trend adoption.
  • Keep UX, accessibility, telemetry, and security standards shared.
  • Measure build time, deploy independence, defect isolation, and developer experience.

Reflection Questions

  • Are we solving a real coordination problem or adding architecture fashion?
  • What boundary should never be crossed?
  • What should be shared, and what should remain independently owned?
  • How will a new developer understand the repo and running apps in one day?

Further Study

  • Nx monorepo concepts: https://nx.dev/docs/concepts/decisions/why-monorepos
  • Turborepo documentation: https://turborepo.dev/docs
  • Webpack Module Federation: https://webpack.js.org/concepts/module-federation/
  • single-spa microfrontends concept: https://single-spa.js.org/docs/microfrontends-concept/
  • Martin Fowler, Micro Frontends: https://martinfowler.com/articles/micro-frontends.html