Incremental Migrations with Microfrontends

Learn how to migrate legacy applications using microfrontends
Last updated on June 25, 2025
Frameworks

In modern frontend engineering, the most reliable path from legacy to modern architecture is incremental migration rather than a complete rewrite. Dealing with the inherent issues from swapping out pieces of the application for something different during a migration can be a challenge.

A common pattern to tackle incremental migrations is the Strangler Fig pattern which slowly introduce new features that slowly over time take over the entire old system. Microfrontends can be used with this pattern to break down the application into smaller pieces and moving traffic, features, or users a slice at a time. There are a few benefits to this approach:

  • Incremental progress towards end goal because performance gains and modern DX start accruing as soon as the first slice ships. Developers can start building in the new model to avoid accruing more technical debt.
  • No disruptions to the user by dual running the systems and gradual traffic shifts.
  • Lower migration risk through small, reversible releases instead of a single high-stakes big-bang launch.

The choice of migration strategy will offer different tradeoffs for user experience and ease of development. Two high level strategies for incremental migrations are to migrate the web application page by page, or component by component.

  • Page by page - Build entire pages in the new application, and launch one by one or in batches.
  • Component by component - Move a single component, and share it or embed it in the old and new application.
Migration strategy light.png
Migration strategy dark.png

Page by page is easier and recommended first, but page slices must be chosen well to avoid seams in the user experience. Component by component is more challenging, but a component represents the smallest unit of composability in an application.

A few other factors can also make incremental migrations easier:

  • Monorepos - Monorepos make it easier to share code between applications, simplifying work to refactor code into a common place.
  • Feature flags - Feature flags allow you to easily serve either the old or new experience and helps during development and launch.
  • Observability - Observability is important to make sure there are no errors or degradation in user experience as the migration happens.

In the page by page migration strategy, a single page or batch of related pages are migrated at a time. Users can be sent to the old or new application based on a feature flag.

This approach has a few benefits:

  • Self contained - the new application is simple without any inter-application dependencies.
  • Simple rollout - feature flags that can send users to the old or new application seamlessly.
  • Immediate DX improvements - developers on the new application immediately see the benefits of the new stack without having to worry about the old one.

It is important to consider which pages to start out with to minimize risk and maximize impact. This guidance can help you choose the pages to migrate first:

  • Start small with low risk, high value pages before trying out larger more complex pages.
  • Group related pages in the same batch to preserve a good user experience.
  • Improve team velocity by targeting the most frequently changed pages before tackling the long tail of pages.

Vercel Microfrontends facilitates routing paths on the same domain to different applications by handling the routing of paths to different applications and stitching them together.

Multiple Pages Microfrontends light.png
Multiple pages microfrontends dark.png

To use microfrontends, first create a Vercel project for the new application. Follow the Getting Started guide to create a microfrontends group on Vercel with the old and new application, and then add a microfrontends.json file. In this file, you can specify a flag name to conditionally route traffic for those paths to the new application.

{
"applications": {
"legacy-application": {},
"new-application": {
"routing": [{
"flag": "enable-new-application-phase-1",
"paths": ["/docs", "/docs/:path*"],
}]
}
}
First route the /docs path to the new application when the enable-new-application-phase-1 feature flag is enabled

In each application, make sure to set up withMicrofrontends to configure routing correctly.

import type { NextConfig } from 'next';
import { withMicrofrontends } from '@vercel/microfrontends/next/config';
const nextConfig: NextConfig = {
/* config options here */
};
export default withMicrofrontends(nextConfig);

You can use feature flags to conditionally route users to the new application, allowing you to gradually switch traffic over after verifying that the new application works. Functional testing, observability, and analytics can be used to prove that the new application works. The Vercel Toolbar flags integration also makes it easy for developers to toggle between the old and new application while testing the new application.

Routing Diagram (7).png
Routing Diagram (8).png

If an application is not yet hosted on Vercel, you can create a project on Vercel and use rewrites to route the microfrontends paths to the old application hosted on any provider.

See Vercel Microfrontends - Multi-Zones example for an example of how to use this approach.

When there are no clear pages to migrate separately that wouldn’t affect the user experience significantly, component by component migration can be used. This approach lets the legacy code and new code exist together before the entire page is converted but has some additional challenges associated with it.

  • Extra orchestration, version-skew, and state-sharing challenges must be weighed against the finer-grained control.
  • Performance may suffer as both the old and new tech stack are shared in the same application.
  • JS and CSS isolation may cause issues if the old and new technologies conflict with each other in the same application.
  • Longer timeline to DX benefits since developers must work with both the old and new application until an entire page can be separated out or all the old components replaced.

There are several approaches that can be used to share components between both applications:

  • Iframes - Iframes can be used to embed new components into the old application while isolating JS, CSS, and data. However, they can come with downsides such as difficulty sharing state, communicating with the host application, and UI drift.
  • Monorepo / NPM package - If the code can be compiled into the existing application, a monorepo or NPM package can be used to develop the new components and compile them into the existing application.
  • Wrapper components - Components, such as Web Components / Custom Elements, can wrap the new components and provide an abstraction layer or isolation boundary to the old application making them easier to work with. Shadow DOM can provide CSS isolation so that styles from the old and new components don't conflict with each other.
  • Single SPA / Module Federation - Single SPA and Module Federation are frameworks that allow developers to import modules that can be served from a different application. These frameworks handle compiling the code together allowing developers to share code or load it from a remote source at runtime to enable composition.

Vercel Microfrontends can help with connecting these applications together and improving the developer experience. To get started, create a new microfrontends group with the Vercel projects for the old and new applications. Then, add a microfrontends.json in the default application for the group.

{
"applications": {
"legacy-application": {},
"new-application": {
"routing": [{
"paths": ["/new-app-components/:path*"],
}]
}
}

If using iframes, components can be loaded from the provided paths which will always be on the same domain. When testing in Preview environments, requests from the main app and the iframe will be automatically stitched together to serve the code from the same branch.

If using Single SPA or Module Federation, Vercel makes it easier to stitch together the applications on the same branch if using a monorepo or use developer tooling in the Vercel Toolbar and dashboard.

See Vercel Microfrontends - Pages Router with Module Federation or Vercel Microfrontends - Single SPA + Module Federation for an example.

Migrations are a fact of life for web applications. Incremental migrations can make it easier to migrate between different technology stacks or providers. Microfrontends can help with incremental migrations by providing tools to manage a page by page or component by component migration.

Couldn't find the guide you need?