DEV Community

Peter Ehrenberg for Studio M - Song

Posted on

Micro frontends with Feature Hub

The idea of micro frontends is to split a web app into several smaller applications and still provide seamless integration for the user.

The Feature Hub is an opinionated JavaScript implementation of the micro frontends approach to creating scalable web applications with multiple teams and different technologies.

Motivation for introducing micro frontends can be:

  • divide large, monolithic applications into several smaller self-contained applications
  • facilitate more frequent deployment through small, independent artifacts
  • create the ability to update, modernise or even rewrite parts of the front-end more incrementally than before smaller, more modular and better maintainable code bases
  • scalable organisations through decoupled, autonomous teams with end-to-end responsibility
  • allow a vertical cut along user features (instead of along technical levels)
  • bring together different technologies, e.g. a classic (non-headless) CMS and SPAs by avoiding using the CMS as application platform

The Feature Hub approach

Feature Hub comes with three basic concepts:

Integrator: The integrator assembles the web page from several applications (Feature Apps) and places them into the content on the page.

Feature App: In the context of Feature Hub, a micro frontend is called a Feature App. A Feature App encapsulates a UI feature that can be assembled and reused. Feature Apps can share state (via Feature Services) to enable a consistent user experience.

Feature Service: A Feature Service provides a shared state to the Feature Apps to ensure a consistent user experience. They also allow encapsulation of browser APIs and resources that are not intended to be shared (e.g. history, local storage).

Feature Hub supports the use of any front-end technologies such as Vue.js, Angular or React. Feature Hub also allows different technology choices for the integrator as well as for the Feature Apps. While it is possible to create a custom solution for the integrator tailored to the UI frameworks or libraries of choice, for both React.js and Web Components, Feature Hub provides out-of-the-box solutions.

For their daily work Feature App teams typically build a simplified integrator, which only contains what their FeatureApp needs to run and be tested. This way they do not constantly need to rely on an integration environment, but using their own independent “development integrator”.

Feature Apps should be self-contained, end-to-end and with sufficiently user value or business value, so that a team can develop and operate the application autonomously and independently. Connections to backend systems are in the responsibility of the respective Feature App (and usually done via a Backend for Frontend/BFF). FeatureApps can and should be deployed independently from each other.

The Feature Services are rather lean and only share specific state information between Feature Apps. Feature Services provide a versioned API to enable backward compatibility and thus flexible and decoupled implementations of different Feature Apps.

Our experience after 2 years Feature Hub

The Feature Hub has been created by SinnerSchrader as part of our client work in 2018. In order to facilitate collaboration and reusability, we decided to publish the core functionality of our micro frontend solution as open source (MIT license).

In our client project the integrator in the production environment based on an Enterprise Content Management System/CMS (Adobe Experience Manager/AEM in our case) using Feature Hub.

A nice special feature of our CMS solution is that it allows the author/editor to compose a page equally from modular content elements and also from various Feature Apps. For the end-user of the page, the transitions between a content element and a Feature App should not be visible.

We are currently using the React integrator only. It is capable of rendering Feature Apps which are also built using React on the server as well as on the client (server side rendering/SSR). This enables us to meet the search engine optimization (SEO) requirements of our client.

In the meantime, several teams from the client's company are contributing to our client project worldwide with their market- and use-case-specific Feature Apps using micro frontends based on Feature Hub. Our client's project git has in between several hundred users and over a hundred repositories.

Introducing micro frontends definitely come with additional technical complexity. Before you introduce this into your software, you should definitely ask yourself two questions:

  1. Is it also OK from your user's point of view to split different functions into separate pages so that you don't need deep UI integration?
  2. Do you have still unused options to structure your software in such a way that smaller units can be developed and deployed independently from each other?

In these cases, if I were you, I would try these options first instead the micro frontend approach.

But for all the technical complexity of our project at this scale, our insight is that by far the biggest challenge, and at the same time the biggest opportunity for an optimal user experience, is in the interaction, collaboration and alignment between the different business parties involved.

How to start?

If you want to quickly try out micro frontends based on Feature Hub, as part of the documentation there is a simple demo (todoMVC) available as source and live.

References

#FCKNZS!
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
andreshmosqueda profile image
AndresHMosqueda • Edited

How can I define a service inside "featureServiceDefinitions: []" that is being loaded from a remote location?

As I'm getting:

**The Feature App module at the url "localhost:3004/myFeatureApp.js" has been successfully loaded.

index.js:1 Error: The required Feature Service "test:hello-service" is not registered and therefore could not be bound to consumer "test:hello-component".**

My code:

defineExternals({
react: React,
});
const { featureAppManager } = createFeatureHub("test:container-integrator", {
featureServiceDefinitions: [],
moduleLoader: loadAmdModule,
providedExternals: { react: "16.8.6", "@feature-hub/react": "2.8.1" },
});