Infoxicator.com

Rules of Micro-Frontends

Published

I always wondered how large web applications were built! I discovered the secret a while back and it became my passion. After experiencing the advantages and pains of using Micro-Frontends at scale, I have decided to document this journey and share some of the “best practices”.

This is an opinionated list of best practices when designing applications that follow the Micro-frontend pattern. Each “rule” should be examined and its benefits/downsides evaluated against your specific use case.

Zero coupling between Micro-frontends

To achieve the benefits of this architecture, accidental coupling should be avoided as much as possible; this will unlock the flexibility and scalability that the Micro-Frontend pattern has to offer as well as future-proofing your applications by allowing incremental upgrades or future complete rewrites of parts of your application.

Each Micro-frontend should be able to render in isolation or inside a container application. The data required should be loaded by each Micro-Frontend and avoid data waterfalls.

Do:

  • ✅ Share libraries that can be swapped without affecting other Micro-frontends.
  • ✅ Load all the data it needs to render.

Do Not:

  • ❌ Have a centralised store/share data across different Micro-Frontends.
  • ❌ Share libraries that are in active development.

Separate Code Bases

Each Micro-Frontend should have its own codebase and the version control of choice shouldn’t have any impact on the way the project is developed or deployed. Having all projects under a single monorepo or individual repositories is fine.

Do:

  • ✅ Use Monorepos.
  • ✅ Use individual repos.

Each Micro-frontend should be deployed independently

Each Micro-Frontend should have it’s own CI / CD pipeline and be able to deploy to production on demand without any dependencies on other Micro-frontends. A common antipattern that should be avoided is “The deployment queue of hell” where different Micro-frontends are so tightly coupled that they need to be deployed in a specific order to avoid breaking the application.

Do:

  • ✅ Have separate CI / CD pipelines.
  • ✅ Release on demand.

Do Not:

  • ❌ Have Release schedules.
  • ❌ Have incremental/sequential deployments that require previous versions.

Micro-Frontends should be tested Independently

Because Micro-Frontends are required to render independently as well as inside a container application, it makes sense to also test them independently using unit and integration tests for both scenarios.

Do:

  • ✅ Have unit and integration tests for each Micro-Frontend rendering in isolation.
  • ✅ Run integration tests for Micro-Frontends rendering inside the container applications as part of end-to-end testing.

Micro-Frontends should be versioned

When a new Micro-Fronted is deployed to production, the previous version should not be deleted and the new version should be tagged with a version number using semantic versioning or similar. It is up to the container applications to decide what specific version of a particular Micro-Frontend to use (Managed) or always use the latest version instead (Evergreen).

Do:

  • ✅ Use Semantic versioning.
  • ✅ Use a specific version or “latest”.

Do Not:

  • ❌ Require a global deployment to change versions.
  • ❌ Delete previous versions.

Minimal Communication

Communication between Micro-Frontends should be minimal and simple, avoiding global state and framework-specific solutions as much as possible.

If two or more Micro-Frontends are sharing a lot of messages to provide their minimal functionality, they might be too tightly coupled and they could share a similar enough purpose that they should be considered to be integrated into one.

Do:

  • ✅ Keep messages small and simple.
  • ✅ Avoid state and communication frameworks if possible.

Do Not:

  • ❌ Share state.
  • ❌ Have unnecessary communication.

CSS should be scoped

CSS from loaded from one Micro-fronted should not affect others.

Do:

  • ✅ Scope your CSS.
  • ✅ Use a CSS-in-JS or namespacing library (like CSS Modules).

Do Not:

  • ❌ Use global CSS.

Final Recommendations

  • ✅ Try to create autonomous teams.
  • ✅ Try to arrange your Micro-Frontends around business functionality.
  • ✅ Reusability is a nice “side effect” not the target.
  • ❌ Don’t Force this architectural style just because it is “new”.
  • ❌ You don’t need multiple javascript frameworks.
  • ❌ You don’t need a “micro-frontend framework”.
  • ❌ Micro-Frontends don’t have to be “micro”.

Recent Posts

Do you own a Car 🚗? Here is how to tackle tech debt.

Most developers struggle to explain to product teams why addressing tech debt or refactoring code is important and why it is valuable to the company.

Modular Monoliths: Have we come full circle?

The promise to bring back the “good old productivity win” of monolithic frameworks like Ruby on Rails but keeping the modularity.

The case against DRY, Micro-Frontends edition.

“Don’t Repeat Yourself” How does a modular architectural approach affect the DRY principle?