These are some of the questions I received after my presentation "Micro-Frontends Performance and Centralised Data Caching" at React Advanced London 2021.
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.
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
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.
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.
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.