A software architect's approach towards using Angular (and SPAs in general) for microservices aka microfrontends

This blog post is part of an article series about Micro Apps:


TLDR; To choose a strategy for implementing micro frontends with SPA frameworks, you need to know your architectural goals, prioritize them and evaluate them against the options available. This article does this for some common goals and presents a matrix which reflects the results of the evaluation. To provide some orientation, you also might find this decision tree useful:

Some general advice for choosing an implementation strategy for microfrontends

To substructure a deployment monolith, one could for instance use npm packages or a mono repo. On the other side, a monorepo could also contain different applications. However, in this case you need one of the other integration techniques outlined here if they are parts of a microfrontend architecture.


People ask me on regular basis how to use SPAs and/or Angular in an microservice-based environment. The need for such microfrontends is no surprise, as microservices are quite popular nowadays. The underlying idea of microservices is quite simple: Create several tiny applications -- so called microservices -- instead of one big monolytic applications. This leads for instance (but not only) to smaller teams (per microservice) that can make decisions faster and chose for the "best" technology that suites their needs.

But when we want to use several microservices that form a bigger software system in the browser, we need a way to load them side by side and to isolate them from each other so that they cannot interact in an unplanned manner. The fact that each team can use different frameworks in different versions brings additional complexity into play.

Fortunately, there are several approaches for this. Unfortunately, no approach is perfect -- each of them has it's own pros and cons.

To decide for one, a software architect would evaluate those so called architectural candidates against the architectural goals given for the software system in question. Typical (but not the only) goals for SPAs in microservice-based environments are shown in the next section.

Architectural Goals

Architectural Goal Description
a) Isolation Can the clients influence each other in an unplanned way?
b) Separate deployment Can the microservices be deployed separately without the need to coordinate with other teams responsible for other microservices?
c) Single Page Shell Is the shell, composing the loaded microfrontends a SPA -- or does it at least feel like one for the user (no postbacks, deep linking, holding state)
d) Different SPA frameworks Can we use different SPA frameworks (or libraries) in different versions
e) Tree Shaking Can we make use of tree shaking?
f) Vendor bundles Can we reuse already loaded vendor bundles or do we need to load the same framework several times, if it's used by several microfrontends
g) Several microfrontends at the same time Can we display several microfrontends at the same time, e. g. a product list and a shopping basket
h) Prevents version conflicts Does the approach prevent version conflicts between used libraries?
i) Separate development Can separate teams develop their microfrontends independently of other ones
j) One optimized solution (bundle) Everything is compiled into one optimized solution. You don't have to duplicate libraries or frameworks for different parts of the system.

Normally, you would break those abstract goals down to concrete, measurable goals for you project. As this is not possible in an overview like this, I'm sticking with those abstract ones.


The following table evaluates some architectural candidates for microfrontends against the discussed goals (a - j).

Architectural Candidate a b c d e f g h i j
I) Just using Hyperlinks x x x x x x
II) Using iframes x x x x x x x x
III) Loading different SPAs into the same page S x x x x x x
IV) Plugins * S x x
x x
V) Deployment monolith w/ npm packages * S x
x x x x
VI) Deployment monolith w/ monorepos* S x
x x x x x
VII) Web Components S x x x x x x

An x means that the goal in question is supported. The S in the column Isolation means that you can leverage Shadow DOM as well as EcmaScript Modules to archive some amount of isolation.

While possible, I'm assuming here that one will not squeeze different frameworks into a deployment monolith. This might be a migration strategy but for me it seems like this not an architecture one will come up with upfront.

Also, deployment monoliths do not lead to a typical microservice-based solution. But as the main goal is to reach defined goals, it would be wrong to don't consider these options.

If you are interested into some of those candidates, the next table provides some additional thoughts on them:

Nr Remarks
I) Just using Hyperlinks We could save the state before navigating to another microfrontend. Using something like Redux (@ngrx/store) could come in handy b/c it manages the state centrally. Also consider that the user can open several microservices in several browser windows/ tabs.
II) Using iframes We need something like a meta router that synchronizes the url with the iframes ones. We also need to solve some issues like resizing the iframes to prevent scrolling within them and elements cannot overlap their borders. Also, iframes are not the most popular feature ;-)
III) Loading different SPAs into the same page A popular framework that loads several SPAs into the browser is Single SPA. The main drawback seems to be the lack of isolation, cause all applications share the same global namespace and the same global browser objects. If the latter ones are monkey patched by a framework (like zone.js) this affects all the loaded SPAs
IV) Plugins Dynamically loading parts of a SPA can be done with Angular but webpack and so the CLI demands on compiling everything together. Switching to SystemJS would allow to load parts that have been compiled separately
V) Deployment monolith w/ packages This means, providing each frontend as a package via (a private) npm registry or the monorepo approach and consuming it in a shell application. This also means, that there is one compilation step that goes through each frontend.
Deployment monolith w/ monorepo 
This approach, heavily used at Google or Facebook, is similar to using packages but instead of distributing code via a npm registry everything is put into one source code repository. In addition, all projects in the repository share the same dependencies. Hence, there are no version conflicts b/c everyone has to use the same/ the latest version. And you don't need to deal with a registry when you just want to use your own libraries. A good post motivating this can be found here. To get started with this idea in the world of Angular, you should have a look at Nrwl's Nx - a carefully thought through library and code generator that helps (not only) with monorepos.
VII) Web Components This is similar to III) but Web Components seem to be a good fit here, b/c they can be used with any framework - at least, in theory. They also provide a bit of isolation when it comes to rendering and CSS due to the usage of Shadow DOM.

To make one thing clear: There is no perfect solution and it really depends on your current situation and upon how important the architectural goals are for you. E. g. I've seen many team writing successful applications leveraging libraries and at companies like Google and Facebook there is a long tradition of using monorepos. Also, I expect that Web Components will be used more and more due to the growing framework and browser support.

Some guidance

One way to work with the presented matrix is to extend it with all the other goals you have and evaluate it against your specific situation. Even though this seems to be straight forward, in practice it can be quite difficult. That's why I've decided to give you some (biased) guidance by pointing out the strength of the approaches presented:

If ... Try ...
1) You need just use one microfrontend at one time and have little/ no communication on UI level between them Hyperlinks
2) Otherwise: Legacy and need for very strong isolation iframes
3) Otherwise: One optimized and fully integrated UI, just one technology and no separate deployment Deployment monolith w/ packages and/or monorepo
4) Otherwise Bootstrap several SPAs in one browser window, use Shadow DOM for Isolation, consider Web Components if possible

Macro vs. Micro-Architecture

Here, I'm mainly talking about what I'm calling the macro architecture: It's the overall architecture that hold the micro frontends together. You can also think about it as the glue between the micro frontents. Besides this, each micro frontend has it's own architecture. I'm calling it the micro architecture. And here he can go with the same but also with different solutions as on the macro level. For instance, one could decide to bootstrap several single page applications on macro level and to use web components with them to share widgets. Also, we could decide go go with a mono repo as well as with a specific state management solution on micro level.

The point for me is, that it's a good idea to seperate those two layers when seeking a solution architecture. This prevents that you are ending up in discussion cycles.

It's not an "either/or thing"!

Mixing those approaches can also be a good idea. For instance, you could go with Hyperlinks for the general routing and when you have to display widgets from one microfrontend within an other one, you could choose for libraries or web components.




Angular Schulung: Strukturierte Einführung

Lernen Sie in dieser interaktiven Schulung anhand einer Beispielanwendung den Einsatz von Angular für Ihre erfolgreichen Projekte kennen. Sie durchdringen die Hintergründe und bauen von der ersten Minute an auf Best Practices auf.


Advanced Angular: Enterprise-Anwendungen und Architektur

In dieser Schulung erfahren Sie alles für die Entwicklung großer Anwendungen mit Angular: Mono-Repos, Micro-Apps, State Management, Performance und mehr


Angular: Strukturierte Einführung

Seit der Ankündigung von Angular (2+) fragen sich Entwicklungs-Teams, welche Migrationspfade für AngularJS-1.x-Anwendungen vorliegen werden. Das im Lieferumfang von Angular enthaltene ngUpgrade bietet eine Antwort darauf. Es erlaubt einen Parallelbetrieb von AngularJS 1.x und Angular (2+) und stellt somit die Grundlage für eine schrittweise Migration dar.


Progressive Web-Apps mit Angular

Progressive Web Apps bieten den Komfort nativer Anwendungen, indem sie auf moderne Browser APIs, wie Service Worker, setzen. Sie sind installierbar sowie offlinefähig und nutzen Hintergrundprozesse für Datensynchronisation und Push-Notifications. Diese Schulung zeigt anhand eines durchgehenden Beispiels was sich genau hinter diesem neuen Konzept verbirgt, wie solche Anwendungen mit Angular entwickelt werden und wie Sie in Ihren Projekten von den dahinterstehenden Ideen profitieren.


Reaktive Architekturen mit Angular und Redux

Dieses interaktive Seminar vermittelt, wie Sie reaktive Anwendungen mit Angular entwickeln können.



TypeScript gibt Ihnen alle Möglichkeiten der neuen JavaScript-Standards und zusätzlich ein statisches Typsystem, das dabei hilft, Fehler möglichst früh zu erkennen. Außerdem ist TypeScript die Grundlage für Angular. In diesem interaktiven Seminar lernen Sie diese mächtige Sprache anhand einer Fallstudie kennen.


Weitere Schulungen ...