Micro Frontends: not a silver bullet

An imaginary story, where micro frontends failed

Featured on Hashnode

Micro frontends are a great feat of engineering. If you were able to move your 3 year old React repository to module-federation based micro frontends, it is indeed a great achievement.

However, I feel there are a few situations, where micro frontends are not a perfect fit. Here's a completely imaginary story of an application's evolution.

The story

So, there's this team of front-end developers and they intend to rewrite their web application. Like all great react application, they too started to write their code with create-react-app boilerplate and redux.

Chapter 1: Issues with scaling the UI

Soon there were demands for more and more routes and journeys in their react application. The team size increased from 3 to 9, so they were divided into 3 teams. So, there are now 3 teams working on the same codebase, and the delivery challenges were slowly surfacing, challenges like

  • Regression Issues and testing: Even if you don't change anything in a particular journey, just that it is getting rebuilt, so formal testing is required.
  • Long build time: It now takes 20 mins to run each build, because there were so many unit tests and so much lint/prettier to run.
  • Overlapping responsibilities: Each team were supposed to take care of the journeys, but there are common portions of the code where everyone fiddled.

Project managers were soon fighting among themselves. Some wanted to own all the common parts, some didn't want to own any, and nobody understood the concept of sharing.

Chapter 2: Let's do micro-frontends

So the developers decided to break apart the monolithic frontend repository, and go into a micro front-end architecture. Here's how they split this up.

Module-Federation.png

The lead developer was happy and almost immediately updated his CV mentioning this achievement.

With micro-frontend architecture they were able to solve:-

FactorBeforeAfter
Release autonomyCoupled Deliveries, therefore Risk of regression therefore more testing timeAlmost decoupled deliveries, so less test time
Ownership IssuesEvery developer had the visibility of the whole repository and its architectureEvery team was concerned about their own modules, and the common container and shared code was orphaned now.

This too, however came with some cost.

FactorBeforeAfter
ConsistencyCoding pattern was consistent accross the teamsEach team defined their own ESLint rules as per their comfort level
Unit test benchmarksConsistent accross the repoEach team defined their own ESLint rules as per their comfort zone
ReusabilityMaximumModerate
UpgradesUpgrading dependencies had to be done in one placeAll the modules need to be in the same version, so dependency upgrades are very costly now, and had to be planned.

To address this challenges, the developers came together and proposed going into monorepo with lerna or nx, but the project managers immediately started fighting about the ownership of the repo, and the developers gave up.

So, in a way, micro-frontends are a great thing, with mono-repo, even better, but due to the ownership model, it seemed to be causing more issues now. Smart readers of this post have already started relating this with Conway's Law.

Chapter 3: Let's split ways

So, the developers, decided to split ways completely and now they had 3 react applications.

Module-Federation Finally.png

So, they lost a few great things, like

  1. Reusability: They avoid shared libraries, because no one wants to own shared items. Development is slower now.
  2. Great Engineering: They lost some great engineering they did with micro frontends, or the opportunity of monorepo engineering.
  3. Build pipeline: They now have isolated build and deployment pipelines
  4. No longer an SPA: Since the applications are hosted in different urls now, when the user jumps off from one page to another, a full page refresh happens.

But there were benefits too.

  1. Highest level of autonomy, so better ownership and maintenance.
  2. No cross journey regression.
  3. Each team now can upgrade their applications, or dependencies on their own pace.
  4. Also, the most important benefit here is that the teams will now be able to experiment and evolve, without disturbing the other applications.

The last point about evolution is very important in the field of software engineering. An application ecosystem soon becomes outdated if it does not allow experimentation or evolution. Here's a little quote from the book Jurassic Park.

Every biologist knows that small groups in isolation evolve fastest. You put a thousand birds on an ocean island and they’ll evolve very fast. You put ten thousand on a big continent, and their evolution slows down. Now, for our own species, evolution occurs mostly through our behavior. We innovate new behavior to adapt. And everybody on earth knows that innovation only occurs in small groups. Put three people on a committee and they may get something done. Ten people, and it gets harder. Thirty people, and nothing happens. Thirty million, it becomes impossible. -- Michael Crichton, in Jurassic Park.

At the end: All is well

Although it was a tragic ending that the application was split, but it simplified the releases. It gave us a few learning,

  • Micro-fronends aren't a silver bullet that can fix all UI problems,
  • Reaffirmed our belief in Conway's law
  • It will promote independent discoveries and evolution.
  • Instead of sharing modules or libraries, teams will be exchanging ideas, which I believe, is even better.

Did you find this article valuable?

Support Tirtha Guha by becoming a sponsor. Any amount is appreciated!