Micro Frontends - An exploration

Micro Frontends extend the concept of Microservices to the frontend world.

Just like each Microservice can be an independent world of its own where it can run on separate operating systems, query different databases, and have its own processes, Each Microfrontend could be made up of multiple browser-based components, having its own feature to manage, could be built and deployed separately ensuring that they are independent of each other.

The basic idea behind micro frontends is to think of a web app as a Composition of features and each micro frontend - the frontend for an independent feature often built and managed by different teams.

In the past, these systems were sometimes referred to as Frontend Integration for Verticalised Systems. But Micro Frontends is clearly - a more friendly name 😅

Advantages

Some of the advantages of micro frontends include -

  • More maintainable, decoupled, smaller codebases.

  • The ability to update, upgrade and incrementally rewrite parts of the application, which wasn't easily possible earlier.

Trade-offs

However, micro-frontends come with a lot of baggage to handle as well -

  • Redundant Dependencies - A micro-frontend architecture consists of a set of applications that should be able to work with each other as well, each application has its own set of dependencies, and in the long run each application may have multiple different versions of the same dependency, defeating the entire purpose of using package managers. To avoid this, the architecture must incorporate a way of managing common dependencies and minimising redundancies.

  • Overriding styles, inconsistent designs - Since the micro-frontends by design cannot have their own set of styles, because the overall web application UI cannot look different in patches, there should be a way of enforcing consistency across the web UI. One way to do that could be - integrating styled components, or enforcing a hard-to-deviate-from design system.

  • Communication and performance issues - While developing each part of the application as an independent unit, there should be a way for these parts to interact and communicate with each other, also ensuring that the same set of redundant operations isn't repeated to eventually lead to performance issues is also important.

Implementation of Micro-Frontends

One of the major things to accomplish in Micro-frontend architecture is to establish a way between the host application and the micro-frontends to communicate and integrate.

Build-Time Integration

In this case, the host application or container installs the micro-frontends as dependencies or libraries. This however leads to tight dependency between the host application and each of the micro-frontends, whenever a component gets updated, it needs to be updated in the application as well. The size of the production bundle of the application also increases as a result of incorporated dependencies.

Run-Time Integration

In the Run-Time integration, the server takes the micro-frontends, composes them and renders them as a single web application. The backend would decide which route to request, and it renders the micro-frontend corresponding to the respective route. Nginx Reverse proxy and AWS CDNs are some ways to implement them.

Client Side Composition

In the client-side composition method, the host can be deployed and built separately and the micro-frontends are exposed separately as packages which do not share the same build and deployment processes. Local modules and Remote modules are distinguished. Local modules are regular modules that are part of the current build. Remote modules are modules that are not part of the current build but are loaded at runtime from a remote container.

Loading remote modules are considered an asynchronous operation.

The Webpack 5 Module Federation Plugin is the one of trending ways of implementing this approach.

References

TL: DR;

In this article, we discussed one of the trending paradigms in the frontend world - Micro Frontends, their implementation, tradeoffs and advantages. Try diving into these and relating them to the architectural principles used at your org and in your applications to make informed decisions - In the end, enable a paradigm for building scalable frontends capable of adapting to rapidly changing systems.