Lately, there have been a lot of discussions about micro frontends. It's also a topic, I'm discussing alongside several alternatives in my Angular Architecture Workshops. While this approach can be quite tempting, I also feel that one aspect is completely ignored most of the time: Cutting your domain into self-contained pieces. However, this is the most difficult part and shall be considered before discussing about technical solutions which may include micro frontends.
Why you should cut your domain?
One thing we have learned about sustainable software architectures in the last decades is that we shall reduce coupling to a minimum. The reason is simple: If everything is connected to everything else, we cannot easily modify individual parts of our system:
Hence, it's beneficial to cut your system into small parts that does not need to know (much) about each other. For instance, if you plan an e-procurement system, you might subdivide it into the following so called sub-domains:
According the ideas of domain driven design you would model those sub-domains individually in order to prevent references to similar concpets in other sub-domains.
Unfortunatelly, this is easier said than done. Finding the right cut for your sub-domains is really difficult and you need domain knowledge for it. In order to gain this knowledge, you have to talk with domain experts. There are several techniques for that like event storming.
To be more precise, you need to know the use cases and group them to sub-domains. If you end up with many use cases overlapping the borders of your sub-domains you should question your cut.
I've cut my domain - What's next?
Despite you might have found suiting sub-domains, be aware that you have to even question your domain cut from time to time. Because of upcoming use cases, it could become necessary to move concepts and responsibilities between sub-domains.
Nevertheless, let's assume, you've found the "right sub-domains" for your system. The next question is, how to implement them. A first answer could be to create an integrated solution, aka a deployment monolith, using a mono repo:
I don't have the goal to discuss all the advantages and disadvantages of different architectural styles presented here, but let me stress out that this approach supports a consistent UI and leads to optimized bundles as everything is compiled together.
On the other side, a team responsible for one sub-domain needs to coordinate with other teams responsible for other sub-domains. They have to agree on an overall architecture, the leading framework, and an update policy for dependencies. Interestingly, you might also see this as an advantage.
Also, it is tempting to just reuse parts of other domains which may lead to higher coupling and -- sooner or later -- to breaking changes. To prevent this situation, you can go with free tools like Nrwl's Nx. For instance, Nx allows to define access restrictions between the parts of your mono repo to enforce your envisioned architecture and loosely coupling. I've written about implementing your strategic domain-driven design with Angular and Nx here.
Deployment monoliths, micro frontends or something in between?
To further decouple the parts of your system, you could decide to split it into several smaller applications. If we assume that use cases are not overlapping the boundaries of your sub-domains, this can lead to more autarkic teams and applications which can be deployed separately.
Also, as we are having several tiny systems now, it decreases the complexity.
If you seek even more isolation between your sub-domains and teams responsible for them, you could decide to put each sub-domain into a (mono) repository of its own:
Now, you have something people are calling micro frontends nowadays. This allows the individual teams to be as autarkik as possible: They can choose for their own architectural style, their own technology stack and they can even decide by themselves when to update to newer versions of the frameworks used. This also means they can use "the best technology" for the requirements given within the current sub-domain.
However, this does not come without costs: Now you have to deal with shipping your shared libraries via npm and this includes versioning which can lead to version conflicts.
Also, you have to find ways to integrate the different applications to one big system which is presented to your users. One easy way to accomplish this is using hyperlinks:
Another approach discussed a lot nowadays is providing a shell that loads different single page applications on demand. As discussed an an previous article, each of those solutions has its very own advantages and disadvantages.
It's about your sub-domains!
As you have noticed here, finding a solution for implementing micro frontends or even discussing about the sense of micro frontends is not the first thing you should concentrate on. First of all, you need to find suitable sub-domains. Only then, you can really concentrate on feasible solutions for implementing them.
For instance, if there was no way to prevent that use cases are overlapping the borders of sub-domains or if you see that the users have to switch a lot between them, using hyperlinks for integrating them might not be the best idea.
Furthermore, you also need to know your architectural goals to evaluate the possible implementation techniques, which is something I've discussed here. Do you need a mix of technologies? Do you need separate deployments?
Finally, I have a good message for you: If you know your sub-domains as well as your architectural goals, it's not that hard to choose between the available implementation options anymore. One reason is that with this knowledge you can rule out all the non feasable ones. Also, evaluating the advantages and disadvantages of the feasable ones becomes easier in this situation.