DEV Community

Cover image for Micro-Frontends FAQs
Ruben Casas
Ruben Casas

Posted on • Updated on • Originally published at infoxicator.com

Micro-Frontends FAQs

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.

Discussion (15)

Collapse
jfbrennan profile image
Jordan Brennan • Edited on

Regarding global state...

I've successfully used a cookie for small bits of shared state in micro-frontend envs at two large companies (20+ web apps each).

Cookies are transferred automatically, unlike query params which would have to be maintained at every navigation point (yuck!), and cookies persist across subdomains (app1.example.com and app2.example.com can get to this cookie) and cookies are sent to your servers, unlike localStorage and sessionStorage which can't do either of those things.

Try only storing things like ids, counts, flags, config state, and other small bits. User-focused content should be avoided, e.g. store the id of a product, not all the product info.

Collapse
infoxicator profile image
Ruben Casas Author

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.

Collapse
jfbrennan profile image
Jordan Brennan

β€œnot coupled by an abstraction” yes totally agree. The small data bits should be the raw data. The minute you wrap that data in something you create a three-way dependency. Learned that the hard way.

Collapse
juniordevforlife profile image
Jason F • Edited on

Is there ever a benefit to a small team using the micro-frontend architecture? Why is sharing global state bad?

Collapse
lukeshiru profile image
LUKESHIRU

From my point of view (not an expert, just someone working with micr-frontends at work):

  • Micro-frontends for small teams doesn't make much sense (it barely makes sense in big teams). Is just a solution to a problem ideally you shouldn't have in the first place, but if you do, is "the best" you can get.
  • Global state is bad in general, not only with micro-frontends, mainly because as soon as you make it global you make it insecure, unpredictable and untestable. Is better to have scoped state for everything.

Cheers!

Collapse
juniordevforlife profile image
Jason F

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?

Thread Thread
lukeshiru profile image
LUKESHIRU

Redux, Vuex and Ngrx are "global", but scoped to every micro-frontend, so that's ok. Global state would be stuff like setting stuff in globalThis, or global CSS, or similar.

Thread Thread
infoxicator profile image
Ruben Casas Author

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.

Collapse
infoxicator profile image
Ruben Casas Author

Totally agree! if you don't have that problem you don't need to introduce unnecessary complexity.

Collapse
jfbrennan profile image
Jordan Brennan • Edited on

Yes, just as beneficial to small teams. Been doing it since this architecture was simply called "web apps", that's before the now defunct React monolith was hyped as the Holy Grail.

Micro-Frontends are the answer to an organisational problem

That's not correct. The product size, not organization size is what you look at when deciding to go micro-frontend.

Think about it. Regardless of the size of the organization, breaking a large product into smaller web apps means:

  • Faster to load in the browser (jakearchibald.com/2016/fun-hacks-f...)
  • Faster to build and test (e.g. you made one change to the Dashboard, why are we waiting for the whole monolith to be compiled, tested, and deployed?)
  • Less susceptible to single points of failure (e.g. one app can fail and the rest of the product still works, whereas the whole monolith can be brought to its knees)
  • Easier to experiment with (Components aren't buried in 14 layers of abstractions, mo' freedom baby!)
  • Easier to refactor (if you've ever been faced with rebuilding an Ember monolith you know the pain)

It's really just a coincidence that micro-frontends are also beneficial for large distributed teams.

Collapse
ausmurp profile image
Austin Murphy

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.

Collapse
infoxicator profile image
Ruben Casas Author

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.

Thread Thread
jfbrennan profile image
Jordan Brennan

I don’t find any more overhead than a monolith. The same or even less really in my experience.

Collapse
infoxicator profile image
Ruben Casas Author

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.