These are some of the questions I received after my presentation "Micro-Frontends Performance and Centralised Data Caching" at React Advanced London 2021.
Are Micro-Frontends mainly used for large organisations and when you have multiple teams working on the same page/site or are there any benefits for small teams and solo devs?
That's correct, Micro-Frontends are the answer to an organisational problem, if you don't have that problem then you probably don't need Micro-Frontends. They are useful when you encounter scaling issues and your teams have grown to the point where you start getting friction and your deployments to production have become painful and slow.
There could be some benefits for small teams, for example, if you arrange your application so each developer owns a certain part of the UI and they deploy that independently. I don't think there are any benefits for Solo Devs because it will add unnecessary complexity to a small project.
How do you share global state?
The answer is you don't. Global state could cause coupling between Micro-Frontends and add a central dependency that could block or stop independent deployments. The best recommendation when working Micro-Frontends is to avoid coupling at all costs because if you don't you might end up with a distributed monolith and none of the benefits of Micro-Frontends.
Now, how do you communicate between them? The key is to keep the messages small and to a minimum, respect the system boundaries and have strong contracts that guarantee the encapsulation of your Micro-Frontends. A good example of this is using the Pub/Sub model and the postMessage()
API.
How do you maintain coding style and conventions over multiple Micro-Frontends and teams working on them?
People think Micro-Frontends are bad for consistency, however, this is not an issue related to this architectural pattern; this is an organisational issue and as such, your company and teams are responsible for keeping coding standards and maintaining style consistency by implementing something like a Design System. Micro-Frontends could be good for consistency by allowing you to reuse certain parts of the application like the header and the footer.
How do you share common components? Do you create them as Micro-Frontends or do you create a component libary and consume it as a normal npm dependency?
I would recommend a component library, however, the key to making it work well with Micro-Frontends is to have well defined atomic components instead of large pieces of UI. Also, it is important that the library is stable (not in active development) to avoid coupling. If you are constantly making changes to the base components, all your Micro-Frontends will need consume those updates which can create a bottleneck and slows down independent deployments.
How do you ensure all teams update to the latest version of a shared dependency at the same time?
If this is a dependency, then you just follow the normal process of communicating the update to your consumers and they will have to install and deploy their codebases to reflect the latest changes.
If you want to update a Micro-Frontend and you want all your users to consume the same version, for example, if you want them to consume the same version of the header or footer then you can use two different approaches.
The first one is the "evergreen" approach, where all your consumers always point to the latest version as soon as it is published.
The second approach is the "managed" approach, where you publish your Micro-Frontend and follow the rules of Semantic Versioning so consumers can choose what version to use; the difference of this approach from a standard npm dependency is that you can start consuming the new version at runtime without the need to install and deploy a new version of the application that is consuming it.
Top comments (8)
Is there ever a benefit to a small team using the micro-frontend architecture? Why is sharing global state bad?
There could be some benefit, for example, if each dev works independently and is responsible for a section of the application, then micro-frontends could help scale and improve developer speed, however, the benefits are better when dealing with large scale apps and multiple teams.
Regarding state, the problem is that if you have an abstraction that provides a shared state across micro-frontends, you introduce a centralised place that you have to update in order to be usable by other micro-frontends, in this case it creates coupling and you lose the benefits of independent deployments.
There can always be a use case. I work on a very small product at a startup, and even I have a use case. We have an image viewer that is needed in 2 completely different places, one in the react app and the other on our main website to show customers what they can do.
Thanks @lukeshiru . I'm on a pretty small team and we've been developing a new app using a micro-frontend architecture. I've been curious about other developers perspectives regarding micro-frontends and their use case.
When working with a micro-frontend architecture, does it make sense to use a state management library like Redux/Vuex/Ngrx? If not, how should state be managed?
Those tools could be used, however, they make it easier to couple micro-frontends, as long as you only use the global state to share messages rather than depending on that state, it should be mostly fine. Another issue is including an extra dependency, but that could also be handled if designed in a way that they remain independent.
Yes! cookies are great to share some information between Micro-frontends, it is particulary useful when dealing with authentication. (using HTTP only secure cookies instead of localstorage). The key here is that the data shared is small and that the Micro-Frontends are not coupled by an abstraction.
Agree it also depends on the size of the product, however, it is important to asses if the extra complexity is worth the effort. In some cases it is fine, but usually large orgs have more resources hence it is easier to absorb the additional overhead.
Totally agree! if you don't have that problem you don't need to introduce unnecessary complexity.