Modernizing a large multi-team application with Micro Frontends

Modernizing a large multi-team application with Micro Frontends

PUBBLICATO IL 27/06/2025 DA

Leonardo Montini

Development

Here’s a quite common scenario: you have a web application, built years ago, with deeply intertwined modules and dependencies. To make things worse, there are layers of legacy code built on top of each other, and multiple teams are dealing with the same codebase daily.

Each team struggles to implement new features without stepping on each other’s toes, app-wide updates are a long and dangerous process and updating only a portion is just adding one more layer of tech debt and inconsistencies.

The result? Slower development cycles, frustrated developers, and a product that struggles to keep up with user expectations and the market in general.

One of our clients has been in a similar situation, here’s how we’re taking care of that with Micro Frontends.

Modernizing with Micro Frontends

The main React application has almost 10 years and is bundled with an old version of Webpack while the new micro frontends are React apps running on Vite.

The approach is to gradually extract smaller applications from the old system, using the long-time domain and project knowledge to properly know where to set the boundaries.

Each smaller project has a unique goal in the system and is assigned to a dedicated and autonomous team. This brings a lot of advantages as each team can independently develop, deploy, and maintain their own portion of the system.

Communication between the systems is mostly through custom events.

With that in place, micro frontends enable incremental upgrades, allowing the legacy codebase to coexist with the new technologies. The teams can replace old modules one by one rather than rewriting the entire application all at once.

Downsides you better not ignore

Before going all-in into your next huge refactor to adopt micro frontends, there are some downsides you must understand.

To begin with, to reduce complexity of your old legacy system you’re going to adopt an architecture that for sure fixes some of the flaws but also brings some more complexity in other areas of your application. To name a few, passing data between components of a single app might be trivial nowadays but sharing the state and communicating between micro frontends might not be that obvious. There’s plenty of solutions, but the team must get used to them.

Separating all the moving parts might seem a simplification but now you must handle each one of them independently, including deployment and versioning. It’s an aspect you might see as a benefit, but it undeniably adds complexity.

Consistency can also be a challenge if not handled properly, as autonomous teams can easily drift and lose sight of the bigger picture. A common outcome can be large differences in UI components giving an unpolished look at the final product.

DOs and DON’Ts

A few tips to guide your implementation to maximise the benefits and avoiding some common mistakes. Some of these are common sense, some we banged our heads on during the project.

DOs

  1. Do define clear boundaries for each micro frontend
    We all should have learned the lesson from microservices, using the wrong criteria to break down the monolith and set boundaries will inevitably do more harm than good. Make sure each micro frontend represents a distinct feature or domain.
  2. Do ensure independent deployment
    Micro frontends should be deployable independently. If you end up in the situation where you consistently can no longer deploy one sub-system by itself, you’re coupling too much and losing the benefits of having separate frontends.
  3. Do use shared libraries
    Leverage shared libraries for common functionality like design systems, authentication, or API clients to reduce duplication of logic and inconsistencies. Module federation easily allows setting up shared libraries, use it.
    This should also help in making sure the user experience remains consistent through a centralized design system.
  4. Do start small
    Begin with a single feature or module to test the waters. Gradually expand the micro frontend architecture as you gain confidence and refine your processes.
    If you’re transitioning from an old and large system this is even more relevant to avoid unexpected issues.

DON'Ts

  1. Don’t overcomplicate your architecture
    Once you unlock the power of splitting into separate apps you might enjoy it too much. You can’t look at micro frontends as if they were simple folders in your monolithic app. Splitting and organizing components into separate folders is as easy as (auto) updating the imports, doing the same over many micro frontends can be way more painful.
    Avoid immediately splitting your application into too many micro frontends without a strong rationale.
  2. Don’t ignore cross-team collaboration
    While micro frontends promote autonomy, teams must still collaborate to ensure consistency and avoid duplication. Regular communication and alignment are essential. Some code and logic will be duplicated, that’s fine, just make sure it’s intentional and under control.
  3. Don’t use different frameworks for the sake of it
    Although micro frontends allow flexibility in technology choices, using entirely different frameworks (React for a module and Angular for another) can complicate integration and increase onboarding time for new developers.
    Just because you can doesn’t mean you should.
  4. Don’t forget testing
    Each micro frontend must be thoroughly tested both independently and as part of the larger application. Skipping integration tests can result in unexpected issues when modules interact with each other.
  5. Don’t forget about versioning
    Proper version control is critical for shared libraries and APIs used across micro frontends. Ensure backward compatibility to avoid breaking changes that disrupt other modules. If you end up having breaking changes all the time, maybe moving over to micro frontend wasn’t the right choice (or you’re doing it wrong!)
  6. Don’t skip documentation
    Document the architecture, module boundaries, communication protocols, and deployment processes thoroughly. This ensures smooth onboarding for new developers and reduces confusion over time.

Conclusions

Micro frontends are indeed an interesting and valuable architecture bringing several benefits, as in our case it allowed us to gradually upgrade the system without the risks of a full rewrite by keeping the teams almost independent from each other.

However, it’s worth mentioning that it’s not always the best solution and it should be considered only if some conditions are met (application size, team(s) size, technical complexity, etc...). Smaller applications or teams may not benefit from the added overhead of managing multiple micro frontends, and simpler architectures might suffice for less complex systems.

This architecture doesn’t magically get rid of complexity, but it shifts it to other places trying to make it more manageable. If you and your team are not ready to manage that new kind of complexity, think again if this is really what you’re looking for.

As always, bad adoption of good practices can do more harm than good, do your research thoroughly and if you think you’ve got what it takes, then go for it and enjoy the flexibility of micro frontends!


Contatta i nostri esperti

per parlare di come possiamo aiutare te e la tua azienda ad evolvere

Contattaci