Designed by Martin Stoleru. Developed by Alinus Dumitrana

All Articles

Microfrontends in Practice: The Good, The Messy, and The Migration

Working inside a real microfrontend architecture — what it's actually like when Next.js, Angular, and React microfrontends coexist in production.

Written By Alinus Dumitrana

I recently spent several months working on a large fintech platform that uses a microfrontend architecture. Not a greenfield "let's try microfrontends" project — a real production system that evolved into this shape over years. Here's what it actually looks like from the inside.

The Architecture

The setup, simplified:

  1. Next.js is the main shell application. It handles routing and renders most new pages.
  2. Angular is the legacy monolith. Pages that haven't been migrated yet fall through to Angular.
  3. React microfrontends were an earlier migration attempt — standalone apps loaded into specific routes.

The flow for any given URL: Next.js checks if it has a page for that route. If not, it loads the Angular app as a fallback. The Angular app might then load a React microfrontend for certain sections.

Next.js (shell) → Angular (fallback) → React microfrontend (optional)

Yes, three frameworks in one user session. Yes, it works. No, it's not elegant.

Why It Ended Up This Way

Nobody sits down and designs this. It happens incrementally:

  1. The product starts as an Angular monolith.
  2. The team decides to adopt React. Rather than rewrite everything, they build new features as React microfrontends that load into the Angular shell.
  3. Later, the team decides Next.js is the future. The new shell is Next.js, which loads Angular as a fallback for unmigrated pages.

Each decision made sense at the time. The result is complex, but the alternative — a full rewrite — is almost always worse. You'd spend months rewriting while the product team waits, and you'd introduce new bugs in already-stable code.

What Makes It Work

Shared design system. All three frameworks render components from the same design system. This is what makes the transitions invisible to users — they don't know (or care) that the page they just navigated to is running a different framework.

Independent deployments. Each microfrontend deploys independently. A bug in the React checkout flow doesn't block a fix in the Angular account settings.

Feature flags for migration. When we migrated a page from Angular to Next.js, we'd put it behind a feature flag. Roll it out to 5% of users, verify nothing breaks, then gradually increase. Rolling back is just toggling the flag.

What Makes It Hard

Shared state is painful. Authentication tokens, user preferences, cart data — anything that needs to be consistent across frameworks requires careful coordination. We used a combination of cookies, URL parameters, and a thin shared JavaScript layer.

Testing is complicated. Unit tests work fine within each framework. Integration tests that cross framework boundaries are harder. E2E tests are essential — they're the only thing that verifies the full user flow works across all three layers.

Bundle size. Yes, the user downloads Angular, React, and Next.js. We mitigated this with aggressive code splitting and lazy loading, but it's a real cost. The first load is heavier than a single-framework app.

Developer onboarding. New team members need to understand all three frameworks and how they interact. The mental overhead is significant.

Migration Strategy

The long-term goal is consolidation into Next.js. The approach:

  1. New pages are always built in Next.js. No exceptions.
  2. High-traffic pages get migrated first — more user impact per migration effort.
  3. Low-risk pages (static content, settings) are good candidates for newer developers to migrate as a learning exercise.
  4. Each migration includes adding proper test coverage that didn't exist in the Angular version.

I spent some time during an innovation day prototyping an AI agent that could assist with these migrations — analyzing Angular components and suggesting Next.js equivalents. It's an interesting idea for reducing the manual effort, though it needs more work before it's practical.

Would I Recommend Microfrontends?

For most teams, no. The overhead is significant, and you need a certain scale before the benefits (independent deployments, team autonomy) outweigh the costs (shared state complexity, testing difficulty, bundle size).

But if you're already in a microfrontend architecture — because the codebase evolved that way — the answer isn't to panic and rewrite. It's to migrate incrementally, maintain a shared design system, and invest in E2E testing. The architecture works. It's just not simple.

Other articles