Microfrontends

In a nutshell, microfrontends are business components for the web: Each microfrontend solves one particular business problem. These may be things like a product search, a map with points of interest, an interactive product promotion, or a gallery for hotel images.

Below, you see a Simple Hotel, built as a microfrontend:

It is simply embedded into the web page. The integration does not require any sort of framework or knowledge about internals of the microfrontend. In fact, you could open the source of this page, copy a few lines of code and embed the same microfrontend into any other web page.

Building Websites With Microfrontends

Microfrontends can be used stand-alone, but usually they are combined into larger applications, such as a sales platform. In the following graphic, each of the blue-bordered boxes is one microfrontend: The main ones provide search, filter and result capabilities for a flights shop, but even the smaller ones at the top (site search, favourites, shopping cart) are microfrontends in their own rights.

Microfrontends on a page

By “slicing” the website into multiple independent blocks, capabilities can be delivered in parallel. As microfrontends are loosely coupled and expose a clearly defined interface contract to their environment, there is no risk of breaking the platform with this decentralised approach.

Patterns

There are different ways of building a microfrontend-based website. At TUI, we have chosen the client-side integration approach, meaning that our microfrontends are web components and integrated into a web page in the browser. We have chosen this approach mainly for two reasons: First, it allows a team to deliver updates of their microfrontend to the client at any time, without a dependency on a build pipeline. Second, by encapsulating all HTML, CSS, and JavaScript in the Shadow Root of a custom element, we achieve a strong separation of the microfrontend from its environment.

Architecture

It is important to note that microfrontends are far more than fancy widgets on web pages. In fact, a microfrontend is a self-contained full-stack web application which usually, despite its name, also contains backend and persistence functionality. Together with other microfrontends it is integrated on web pages, which in such an architecture act as mere integration points.

Horizontal to Vertical

This architectural style is called “verticalisation”: Instead of building large web applications in layers that are driven by technical concerns, they are build in full-stack components defined by a logical scope. As such, microfrontends are related to microservices which also are self-contained and part of a loosely coupled ecosystem as well. Even more, they extend the paradigm of service-based decoupling to the frontend of a web application.

Composition

Microfrontends themselves are not web pages; they need some sort of containing page in which they are integrated. For this purpose, statically generated pages are a perfect complement.

Horizontal to Vertical

In such an integration context, microfrontends communicate asynchronously through browser events. This means they don’t directly speak to each other, they don’t even know about each other. Instead they are managed by an integration layer which is aware of all microfrontends in the current context and orchestrates them.

Take for example the above flight search page: When the “search flights” button is clicked, all the search form microfrontend does is emit an event with the search parameters. It is then the job of the integration layer on the page to forward these values to the results list microfrontend understands. The results list microfrontend (NB: not the integration layer!) will then load flight results for the given search configuration and display them.

This may seem overly complicated, but this way, both the search form and the result list can be developed independently. And if necessary, the integration layer can translate the data structures between them.

The OpenMFE Specification

In order to achieve the objectives of loose coupling and evolvability, we need rules that govern the interoperability of microfrontends without taking away the freedom of teams to build their microfrontends in the best possible way. This is why we have developed the OpenMFE specification which governs how microfrontends need to behave at runtime. It contains general provisions that describe how encapsulation is achieved as well as rules for prerendering and semantic data. Finally, it contains a formalised way to describe the interfaces of a microfrontend in a manifest file. To understand the rationales behind the specification, please have a look at the OpenMFE considerations.

Frameworks

There are different frontend frameworks which are more or less suited for building microfrontends. In our case, however, the best framework is no framework. This may seem strange, but the reality is that the native functionality of browsers has become very powerful over the last few years, and as we don’t need to support old Internet Explorer or Edge browsers, there’s not much missing! Of course, we use libraries for things like localisation or other purposes so that we don’t have to reinvent the wheel, but we will think very hard before we decide to use a framework like React that adds a lot of overhead in terms of code and client resource usage.

Curious To Learn More?

If you would like to learn more about the development of a microfrontend, please have a look at our intro tutorial with a step-by-step analyisis of a real, yet simple microfrontend.