Nowadays, we are witness to a growing interest in microservices-based architecture, which generally relates to the writing and integration of back-end software. Microservices bring a plethora of benefits to the development process, allowing a high level of modularity, increasing maintainability and decoupling modules from each other, reducing functional dependencies to the minimum.
The benefits of microservices are obvious, so it should come as no surprise that, in the last few years, a new paradigm has also arisen for front-end development, usually referred to as micro-frontend.
The idea behind this concept is that a single front-end application doesn’t necessarily need to be monolithic, but the option exists to design it as a composition of diverse features which are independently developed. An orchestrator can then put all these features together to provide, from the user’s point of view, a unique frontend.
This article explores micro-frontend architecture, following the experience of Soldo, a Fintech company active in spending management services, that transitioned its web console application from a monolithic frontend into a more modern micro-frontend architecture.
The benefits of micro-frontend – not just from a development point of view, but also looking at how teamwork is (positively) affected by such a technological paradigm – are also discussed in what follows.
From monolithic to micro-frontend
The micro-frontend paradigm has been defined as an alternative to monolithic architecture. The traditional way of designing and implementing front-ends consists of building a feature-rich and powerful browser application, which sits on top of a backend architecture (now often made up of microservices).
Over time, the front-end layer, often developed by a dedicated team separate from the backend-focused team, grows and becomes more difficult to maintain. This is usually referred to as a front-end monolith.
This describes the state of play at Soldo in 2017, where their web console was entirely written in AngularJS with proper modular decomposition. This approach was reasonable, when you consider the dominant trends and the team size, limited to a few developers.
The small size of the team also had some advantages: it eased communication among the front-end, the back-end, and the design sub-teams. This helped in converting functional requirements into something coherent and effective from the users’ point of view.
With time, the company’s size increased – not just in terms of people but also from a software point of view. Additional needs arose, and maintaining a single monolithic front-end became complicated due to its modules’ interdependence.
New team members needed to be trained to interact with the existing code base, and this slowed the development process. Finally, communication among sub-teams became more rarefied, because of the increasing number of people involved in the project. Managing the introduction of additional features and their release was not straightforward at all.
To retain a good level of maintainability while improving the general developer experience, Soldo moved towards an original architecture, and opted for micro-frontend.
Each module can be developed with the preferred framework, with no limitations in using Vue, Angular, React or – potentially – anything else the developer prefers. With single-spa, different technologies can be adopted for different modules, and the library allowed to “mix” them together in a unique front-end.
The technology duly selected, the migration inevitably needed a transition time. The first step was to convert the whole monolithic application written in Angular into a single micro-frontend (even if it would be more correctly described as a “macro-frontend”). Then, this macro-module was registered in a single-spa and used as the first module within the new architecture.
Following this first change, the next steps came naturally: individual features were gradually moved from the original monolith to new micro-frontends, each of which was developed completely differently.
The entire team was divided into multiple small vertical sub-teams, each of which focused on a single feature. This in some respects restored the original idea: having a few people developing a single application, but with the advantage of better communication among designers, front-end and back-end developers.
It is also worth mentioning that this choice allowed Soldo to switch to a different paradigm without pausing the company’s core business: the new front-end based on single-spa was deployed just like any other release.
From the first deployment to those which followed, any additional feature was added seamlessly, without interrupting primary services. This was possible because of modularity and the ease this creates in switching among the different micro-frontends.
Advantages of micro-frontend architecture
The transition from monolithic to micro-frontend described above has several advantages. The micro-frontend’s positive points are summarized below:
The first advantage derived from the use of micro-frontends is related to deployment and release. A monolithic architecture requires longer build times, and it is difficult to schedule a new release without coordinating this with the development of all other modules.
With their low or even non-existent interdependency it is extremely easy to develop and test the various micro-frontend modules. It is easy even to rollback to a previous version should a function not work properly, without blocking the entire architecture.
Of course, deploying a new module is much faster and scheduling new releases is more flexible.
Given the rollback function, this architecture is effective for any situation that involves introducing a new technology.
Ten years ago everyone used jQuery, but today React or Vue are two of the most commonly-used front-end frameworks. With single-spa (or any other micro-frontend implementation), you can easily introduce a new technology by using it to implement new modules, deploy, and see if it works.
Even if the result is not satisfactory, rolling back to the previous version is quick and easy. This allows companies to innovate in a much more agile and flexible way than before.
We already touched on another great advantage of micro-frontends, and Soldo provides a perfect example of this. Small teams have the advantage of ease of communication among designers and developers, front-enders and back-enders. However, as the application grows, so does the team and everything becomes much more difficult.
To solve such limitations, the creation of small vertical teams focused on a specific feature or module is a brilliant solution.
If developed together with a microservices-based backend, a micro-frontend helps in reaching this goal. By dividing the whole development into functional modules at all levels, one-to-one mapping can be established between the features to be developed and the sub-teams working on them.
This is possible thanks to the modules’ independence – a single vertical sub-team can develop a discrete module with very limited knowledge of the entire architecture.
It is worth mentioning that one of the first micro-frontends was developed by a newly hired front-end developer immediately following the migration from Angular to single-spa. This developer teamed up with other members working on the back-end, and designers.
The new hire did not need any training on the architecture and could start working on the new module with React. The new module worked just as expected.
The micro-frontend architecture also improved the general developer experience. Single-spa provides an interesting feature, based on import-maps overrides. This essentially allows the developer to test the new micro-frontend module in a browser where the rest of the application is deployed.
With this capability, deployment of a separate test environment is unnecessary since the already deployed application can be exploited by overriding the module you want to replace; testing the new module is almost seamless.
Another plus of micro-frontends is teamwork. Traditionally, developers often work on the same application, making their work repetitive and boring. Making new vertical sub-teams for each additional feature, any team ends when the feature is completed. At that point, team members are individually reassigned to a new feature.
This approach makes the development process a much more varied and interesting one as developers get more opportunities to learn something new.
Graphical assets management
Of course, nothing good comes without drawbacks. However, with micro-frontends and in Soldo’s experience, such drawbacks appear quite limited.
The most significant issue is related to graphical assets management, including images, styles and SASS/CSS code. Here, you always need to have something that cannot be completely independent of other modules, since you want the application to appear uniform from the user’s point of view.
To address this issue, Soldo’s design team defined a shared code base of CSS/SASS and other graphical assets, while additional code was added for each micro-frontend as needed.
This is manageable, although it lacks the independence of other modules. It seems a good trade off as it keeps the whole development still effective.
Micro-frontend architecture has many advantages. It allows teams to ease development in a straightforward way; it is extremely modular, more agile and (almost) completely independent from the main architecture. This way it allows greater focus on innovation.
Rollbacks offer the development team security while providing new features, without ever putting core business on hold.
This also helps improve the developer experience, as Soldo’s case study testifies. Building small vertical teams and creating new ones for every release offers developers the opportunity to change the focus of their job regularly. This eliminates repetitive tasks and ensures developers are always learning something new.