bene : studio is a global consultancy, helping startups, enterprises and HealthTech companies to have better product

Using micro-frontends architecture to build more scalable applications

micro-frontend architecture

At bene : studio, we love knowledge sharing to help the community of professionals. With 10+ years and over 100 projects behind us, we have a vast amount of experience. This is why we have launched a knowledge base on our blog with regular updates of tutorials, best practices, and open source solutions.

These materials come from our internal workshops with our team of developers and engineers.

Pardon the interruption, we have an important message!

We are looking to expand our team with talented developers. Check out our open positions and apply.

What are micro-frontends?

“Micro-frontends” is a term that represents the extension of the microservices idea into the frontend world. The idea behind micro-frontends is to replace monolithic single page applications with a set of smaller modules (frontends). Thus, making frontend projects easier to maintain and more scalable.

Relation between microservices and micro-frontends

Microservices is the architectural style in which software is built as a set of loosely coupled services with separate responsibilities.

Micro-frontends adopt this style and build frontend applications as a set of smaller frontends with shared communication channels to allow these modules to send/receive data and react to events.

Advantages of micro-frontends over monolithic frontend

Can be developed using multiple technologies

Just like microservices, micro-frontends are independent units that can use their own technology stacks, so that when you’re building a project you don’t have to stick to the initial framework choice and be doomed to continue your development in it for the entirety of the project, It also means that when your code starts getting outdated, you don’t have to rewrite everything from scratch. You can gradually port features to micro-frontends using cutting-edge technologies.
Just remember: “Because you can use different frameworks and technologies, it does not mean that you have to”.

Reduces chances of “Single point of failure”

Monolithic applications suffer heavily from the “single point of failure” problem.
What is a “single point of failure” or “SPOF”? According to Wikipedia, the definition is:

“A single point of failure is a part of a system that, if it fails, will stop the entire system from working.”

Wikipedia

Because of the nature of monolithic apps as a single entity, a bug can break multiple features or completely stop the whole application from working.
Micro-frontends architecture reduces the chances for a SPOF by distributing features over separate applications, each achieving a specific business goal. If one thing breaks, it doesn’t have to break others with it.
BUT, note that here the term “reduce” is used, not “eliminate”. This is mainly because you will still have a container (sometimes referred to as “Bootstrap”) application that contains all the micro-frontends as children, handles routing and positions those child frontends. Issues with this container application can affect the other apps.

Smaller and more maintainable codebases

One con to monolithic applications and a pro for micro-frontends is how the codebase grows with the size of the application, in the case of a monolithic design. Micro-frontends do not suffer from this issue as each part of the application is its own isolated module with its own codebase, leading to smaller, simpler, and easier to manage projects.

Easier work among multiple teams

This can be broken down into more than one point:

  • Autonomous teams: teams become independent as each takes responsibility for a specific project with a specific goal, allowing the teams to move faster and become more productive.
  • Easier onboarding: onboarding new team members to the now smaller frontends are much easier than to one big monolith. The new team member can see with more clarity the role of each part of the project and in turn the code of that project, speeding up the process of onboarding and time until a new team member is capable of contributing to the project.
  • Easier Cooperation with 3rd party teams: the autonomous nature of a micro-frontend and the ease of plugging in and out new micro-frontends in the final product makes it especially easy to allow 3rd party teams to develop part of the project. This helps build extensible frontends which are able to host new plugins/widgets/apps/frontends developed by 3rd party teams. 

Separate deployments

Each micro-frontend should have its own independent deployment pipeline, fully customized to the case of this part of the project. The final result of the deployment should be a new live version of only this part of the project. The independent nature of micro-frontends allows for independent deployments without having to worry about the current state of other parts of the final product. This allows gradual upgrades to features without much worry about breaking existing well functional parts of the product.

Downsides of micro-frontends:

Loaded javascript size

Since each project can have its own stack, or even if they all use the same technologies independently, the bundling for each micro-frontend is done independently, allowing each to build and run on its own. This bloats the overall size of the app since the dependencies are not shared even if the same dependency is used by more than one of the micro-frontends.

Development environment management

It’s a pro for micro-frontends that they can be developed independently. You can test in isolation from the rest of the project, then deploy to production and run inside the container app.
The problem is ensuring that this module works as expected with all the other modules, especially for projects with lots of micro-frontends and heavy communication/data-transferring between them. Because although the app’s code is decoupled from other projects, they all eventually work as one entity.
Issues can also happen when the app is developed in isolation from the container application, which might have global styles that affect this app, or the containing html element has maximum height/width or a scrollable behavior that the app developer needs to adapt to and cannot test in isolation.

Operational complexity

One of the major challenges with micro-frontend projects is how to manage all of them. Having more independent teams has its benefits, but it comes with more management workload as well. There need to be enough people to work on the project, enough resources for the deployments of all the independent applications and also the automation of it, and of course, there needs to be the readiness to handle multiple repositories and a central place to host any libraries/tools made by the team for the project, like the UI library or the standard events library.

Best practices

  • Do not share state – Prefer events over shared states. Shared state causes coupling.
  • Establish project prefixes – Prefixes for local storage and CSS classes.
  • Standardize communication – Set standards for communication between the apps. Separate communication into a reusable package.
  • Lazy loading – Lazy load apps to reduce the amount of data loaded at once.
  • Re-use UI components –  Create a UI library for reuse across micro-frontends

Communication between micro-frontends

Although there are multiple ways for communication between micro-frontends, we will focus mainly on communication over a shared event bus, as it is the most prominent one and also the one we used most at bene : studio.

For this, we recommend using browser-native custom events, but any other pub-sub implementation should work as well.

Using events for communication goes along with the earlier mentioned practice of not sharing state.

Your apps should subscribe to events they’re interested in, and dispatch other events that other apps might be interested in.

The names of those events and the shape of data transported in the event should be well documented and agreed upon among projects/teams.

One good way to approach this is to create a shared library for events that should be used cross-app, the purpose of the library would be to provide utilities that dispatch/listen to standard events and assert the type/shape of transported data.

Conclusion

Frontend development is a fast-moving field, and tons of large-scale projects are now built with SPA frameworks.

Micro-frontends is an architectural style that eases the process of splitting big projects into smaller projects with smaller teams, allowing for easier management of those sub-projects. It also allows for migrating older SPA codebases to new cutting-edge technologies, without the burden of having to rewrite the whole codebase.

The decision to use micro-frontends should be made based on the size/complexity of the project and the resources dedicated to it, and if the project is fitting, you will find that micro-frontends can make life much easier.

Join Our Engineering Team, We Are Hiring!

micro-frontend architecture

Let bene : studio enhance
your digital product!