What are micro frontends?
Micro frontends are a set of principles for structuring large frontend applications, originally inspired by the backend micro-services trend.
While micro frontends are a trending topic of interest, there’s something about them that’s hard to pin down precisely. When understanding a new trend, architecture or technology, it’s often useful to start understanding the problem space first.
There are many resources online that go over the potential benefits of micro frontends that we won’t cover here. Instead we’ll start by understanding the problems they aim to solve. And the trade-offs they make in the pursuit of solving those problems.
What problems do micro frontends try to solve?
The simplest way to understand micro frontends, is seeing them as a technical solution to organizational problems that occur at scale.
For large organizations, with many frontend teams wanting to ship things fast, we’d want those teams to be decoupled. So they can work independently without getting in each others way.
What this means in practice on the frontend:
Independently buildable frontend assets allows teams to own their own builds. This avoids lengthy build times, and prevents individual teams breaking the build for the rest of the organization - blocking others while it gets fixed.
Independently deployable frontend assets allows decoupled these teams to ship their code to production regularly, with without needing to have complex deployment sequences.
This also means when bugs crop up, and incidents occur, things can be rolled back automatically, without disrupting other teams and having their code rolled back as well.
Clear areas of ownership is necessary at scale. In large organizations if no one owns something, it’s almost like it doesn’t exist. Because no one is accountable for keeping it up to date, it often becomes stale and hard to change.
These are some of the core problems micro frontends hope to address. They are legitimate problems, and can be quite difficult to solve. But if solved correctly, it can really accelerate the development speed of teams.
Defining micro frontends
Just as “micro services” is a kind of guiding principle in the backend world, on how to structure services, micro frontends can be seen in the same way.
As a set of guiding principles enabled by specific technologies.
There are underlying technologies like webpack module federation that make a micro frontend approach possible. And popular frameworks like single SPA that provide batteries included set up.
The following principles of micro frontends taken from micro-frontends.org are paraphrased here:
Be technology agnostic means teams can chose whatever frontend tech stack they want. The recommendation seems standardize on web components as common shared primitives.
Isolate team code means focussing on decoupling teams through independently built, self contained apps that are deployed separately.
Establish team prefixes when you have to share stuff. This means a name-spacing for custom event names and things like locale storage and cookies to avoid collisions.
Favor native browser features over custom APIs. This often means using custom elements and web components and custom events for inter micro-frontend communication.
Build a resilient site means build your micro frontends with progressive enhancement in mind.
Some of these are open to interpretation. Which is probably by design, as micro frontends don’t point to a specific universal implementation. That is partly one of the reasons why there’s confusion around what micro frontends are used for.
Potential issues with micro frontends
Micro frontends have noble goals, and aim to solve real organizational issues. However based on their philosophy outlined above, we can see some aspects that would need strict governance in practice in order to not fall into the falling pitfalls:
Potential performance pitfalls. At large scale, giving teams the freedom to chose whatever tech stack they want on the frontend has some significant trade-offs.
In the context of micro-services on the the backend. It makes sense for teams to chose their stack. Because the end user doesn’t need to download and run that code.
On the frontend though, things are different. You end up forcing users to download and run code that solves all sorts of common problems like styling, fetching and mutating data, date formatting etc. Many times over, in different ways, with different tools and frameworks. That’s a lot of overhead.
Can’t we just code split everything? Each micro frontend can be selectively code-split on a page load. Code-splitting isn’t a silver bullet. And it’s often the network waterfall of components loading, then fetching data, which results in more async loading, which is the real culprit of slow page loads. Especially so on mobile, that often has more sensitivity to network latencies.
Difficult dependency management. Even if the same library is shared to solve a particular problem, at scale there is always the problem of different versions of that library needing to be kept up to date. Especially for things like high priority security updates.
Multiple duplicated transitive dependencies lead to users re-downloading the same code (in different versions) multiple times. This is not a trivial problem to manage with lots of teams, even when using a single bundler, let alone one for each independent team.
Inconsistent look and feel. Decoupled teams are often necessary at scale. However often times with completely isolated teams, it’s easy to reinvent the wheel many times over. Leading the overall whole of the application feeling disjointed and janky.
Requires strong governance, oversight and guidelines. Similar to backend micro services. A key question here, is how micro should a micro frontend be?
If we break things down too much we run the risk of creating dependencies that require us to deploy multiple frontends together. Which invalidates a major problem we originally set out to solve.
These points are not to say micro frontends don’t have their use cases. But their adoption should take into consideration mitigation strategies for these potential things to go wrong.
A use-case for frontend framework migrations
In a guide to managing frontend migrations we looked at the “outside in” approach to managing frontend framework migrations.
There is a good potential use case for micro frontends here when you have no choice but to integrate two different frontend tech stacks and adopt a transitional architecture.
Using a framework like single SPA as the application shell to manage the transitional architecture. That said, there are often simpler approaches that don’t require the adoption of a framework that can work as well.
A comparison with the islands architecture
Web frameworks like Fresh, Astro and Marko promote the “component islands pattern”.
Micro frontends on the surface look similar, due to rendering a page build from independent sections of components. But the underlying philosophies are quite different.
The guiding principle for the island architecture pattern is:
- To default to server side rendering over client side rendering.
- Only send what is absolutely necessary to the client for interactivity.
The focus is on minimizing any unnecessary overhead of Javascript.
It’s almost a throwback to traditional multi page architectures, where Javascript was “sprinkled” on on top of server rendered HTML pages to give them a bit interactivity.
In this cycle of innovation, the “sprinkles” are instead component based islands authored using modern technologies like Preact rather than something like jQuery
.
Micro frontends, on the other hand, are all about solving organizational issues, rather than performance ones. And are used in the context of large SPAs worked on by many teams.
Recap
We can understand the rise of micro frontends by looking at the organizational issues they aim to solve.
These are real issues, that if solved correctly, can have a great benefit to frontend teams.
If you don’t have these organizational problems, then you probably don’t need, or want, to adopt a micro frontend architecture.
If you do have these problems, micro frontends are worth checking out. But as we’ve seen they are not without significant trade-offs, often at the expense of the end user, that need to be actively managed.
It’s good to keep in mind micro frontends are not the only way to solve those organizational issues, but that’s beyond the scope of this article for now.