Micro Front-End Architectures
Why And How To Build A Micro Front-End Architecture In Angular
By Jason Neal, Staff Software Engineer, Rocket Mortgage
With the web growing more and more complex, front-end developers are experiencing the same pains that back-end developers faced prior to microservice architectures: large monolithic codebases spread across many domain boundaries, high coupling, bad scalability, slow feature development, difficult merge conflicts and highly coordinated deployments (just to name a few). In this article, I’ll cover a modern approach to front-end software architecture called micro front-end. You’ll learn the core concepts, advantages, disadvantages and integration options with examples in Angular.
What Is Micro Front-End?
Many years ago, it was common to have a single monolithic back-end that was worked on by multiple teams and spanned many domains. With these monoliths, it was impossible to scale more intensive endpoints independently from other less intensive ones. With so many teams working in a single codebase, it was common to have difficult merge conflicts and for deployments to require a high degree of coordination to be successful. This required significant time and led to slow feature development.
Microservices can really revolutionize how you think about architect and build back-end services, but what about the front-end? User interfaces and user experiences have grown more and more complex over the years. However, many are still stuck living with the same issues in their front-end monolithic codebases. So, is there a solution?
Yes! This is where a micro front-end architecture can really shine. Micro front-end is an architectural style in which multiple independently deployable front-end applications are composed into a single cohesive user experience. The term first appeared in the November 2016 issue of “ThoughtWorks Technology Radar,” which currently lists it as a proven technique that organizations should be adopting when it makes sense to do so.
When Should You Use Micro Front-End?
Micro front-end makes the most sense when you’ve got a large front-end product, worked on by multiple development teams, containing many capabilities that cross domain boundaries. A micro front-end architecture can really help your cross-functional teams become more independent and autonomous and help teams to develop quickly and deliver frequently.
However, micro front-ends aren’t a one-size-fits-all solution. If you’ve got a smaller front-end product that’s encased within a single business domain and only worked on by one or two teams, a micro front-end architecture is probably overkill. You can still modularize your application’s capabilities to try to embrace low coupling and high cohesion — and then, if the need ever arises, it won’t be too hard to abstract out parts of your codebase into micro front-ends.
Why Use A Micro Front-End Architecture?
As with everything in life, micro front-end comes with its own suite of advantages and disadvantages. It’s important to weigh the benefits against your concerns to determine if a micro front-end architecture is a good fit for your product.
The biggest benefit of a micro front-end architecture actually isn’t related to the applications and their code, but rather the team’s organization and process. Here are 10 significant advantages that deserve to be explicitly called out:
- Reduces inappropriate coupling across domain boundaries
- Increases each team’s level of autonomy
- Allows for independent testing and deployment of vertical slices
- Enhances comprehension with focus on a reduced scope
- Improves maintainability with smaller codebases
- Enables easier upgrades or replacements of frameworks and dependencies
- Improves ability to incrementally update legacy codebases
- Increases sense of ownership
- Helps cultivate more subject-matter experts in a particular domain
- Promotes reusability with easily identifiable cross-cutting concerns
Of course, you can’t have your cake and eat it too. With a micro front-end architecture, you introduce additional complexities and concerns into your product. Some of these concerns can be mitigated, while others can’t. Here are 10 of the most significant disadvantages:
- Some approaches are only compatible with modern browsers
- Potential for styles to bleed from one micro front-end to another
- Difficult to keep a single cohesive user experience across micro front-ends
- Increase in network traffic may lead to decrease in performance
- Payload sizes increase over time, requiring larger downloads
- Introduces waste as duplicate dependencies are loaded multiple times
- Communication between micro front-end components can be difficult
- Environment differences can lead to “works on my machine” issues
- Increase of stuff to maintain: more repos, tools, pipelines, servers, etc.
- Duplicate efforts across teams solving the same problems in isolation
How To Implement A Micro Front-End Architecture
You have many integration options to choose from when deciding to implement a micro front-end architecture for your product. If you do a search, you’ll find 10 different guides all doing it 10 different ways. However, many approaches are outdated and ill-advised.
I won’t be covering those outdated integration options that use archaic technologies such as Server Side Includes (SSI) or iFrames. Instead, I’ll be focusing on approaches that make sense in modern front-end applications. While my examples will be focused on Angular, these concepts are easily translatable into other frameworks, such as React, as well.
Micro Front-End Frameworks
There are many micro front-end frameworks that aim to reduce complexity and simplify the process of implementing a micro front-end architecture. The most popular framework is single-spa. These frameworks can be helpful depending on your use case, but if you’re already using Angular, I recommend just sticking with Angular for the whole stack. Adding in a meta-framework for your shell is unnecessary and adds undue complexity.
Build-Time Integration With Libraries
Another approach is to simply package each micro front-end as a library. Then, you can pull those micro front-end libraries into your shell application.
Figure 1 — Example Using Angular Libraries
Unfortunately, with this approach, a change to any single micro front-end library requires updating the shell and redeploying the entire product suite. I prefer to avoid this level of coupling and the coordination required to ensure you aren’t pushing another team’s work to production prematurely. If you’ve come this far in your micro front-end journey, your best bet is to just stick with one of the run-time integration approaches I’ll discuss next.
Run-Time Integration With Multiple Single Page Applications
This approach is often referred to as a microsite or micro-app architecture. With this method, you maintain completely independent “micro” websites. You use libraries for common components, such as headers and footers, for design and user experience cohesion. You pull it all together using a reverse proxy, gateway or load balancer to direct traffic to each micro front-end depending on the URL being requested.
Figure 2 — Example Using Multiple Angular Applications
With this approach, changes to your common components will require updating and redeploying all of your micro front-ends in order to maintain brand consistency. This method really takes isolation to the extreme. Yes, it does help keep your micro front-ends completely decoupled, but that comes with a cost of increased overhead. You no longer have the integrity of a single-page application (SPA), so you lose out on the benefits of a SPA as transitions between your micro front-ends require a hard page load. This method also gets complicated if your product requires authentication.
Because of these reasons, I recommend that teams stick with one of the other run-time integration options I discuss below.
Run-Time Integration With Web Components
Figure 3 — Example Using Angular Elements
Based on my research and experience over the past three years, this is the most robust, enterprise-grade, production-ready integration option available today. However, there’s one more approach that has emerged over the past year and is growing in popularity, proving to be a solid contender for the ideal approach of the future: module federation.
Run-Time Integration With Module Federation
Module federation is the new kid on the block in the world of micro front-end architectures, but that doesn’t make it any less mature than the other approaches. It’s one of the new features introduced with Webpack 5 in October 2020. Angular 11 included experimental support for Webpack 5, and with Angular 12, it became the production-ready default.
Figure 4 — Example Using Module Federation
In my opinion, module federation will become the ideal approach in the very near future. As more and more people discover it, I expect adoption to take off and overcome the web component approach, which currently leads this race.
Hopefully this article has helped you better understand what micro front-end is all about. You should be more familiar with the cases where a micro front-end architecture makes sense. You should also understand why the micro front-end patterns are beneficial and the ways in which they may be disadvantageous. Lastly, you should now be more familiar with many of the modern integration options that are widely used in the industry today.
With this knowledge in mind, you can make better-informed decisions about the architectural vision for your products. I hope you take this information back to your teams and organizations to begin discussing if these patterns are a good fit for your products.
Jason has been a software developer for more than 20 years, primarily working in the front-end stack. He’s worked in more than a dozen industries including education, real estate, healthcare, news, radio, finance and more. Jason has always had a passion for building high-quality software. He enjoys pushing himself and his teams to be the absolute best they can be.