Carlos Cifuentes
Micro-frontends · Resilience

Error isolation and resilience in micro-frontends

A micro-frontend platform has more moving parts than a single app, so sooner or later something will fail to load. The goal is that one broken area never takes the whole product down.

By Carlos Cifuentes · Frontend architect · Updated 2026-10-02

Isolation is something you build

Micro-frontends are often sold with the promise that a failure in one area stays in that area. That only holds if you design for it. By default, remotes loaded with Module Federation or Native Federation run in the same document, on the same JavaScript thread, with the same global objects. An unhandled error during startup can leave the user with a blank page, exactly as in a monolith.

The ways a remote can fail

FailureTypical causeWhat the user sees without protection
Remote entry does not loadNetwork error, bad deploy, CDN outageBlank area or a navigation that never finishes
Remote loads very slowlyLarge bundle, slow networkA spinner with no end
Chunk missing after a deployAn old tab asks for files that were deletedError on the next navigation
Remote throws while startingBug, shared dependency mismatchBlank area, sometimes a broken shell
Remote throws while runningBug in a screenFrozen or half-rendered screen

Each one needs a different defense.

Load failures: catch, retry, fall back

Loading a remote is a dynamic import, and a dynamic import returns a promise that can reject. The host should treat that rejection as a normal case.

  • Catch the error where the remote is loaded. In an Angular host this is usually the loadChildren or loadComponent function of the route. Add a catch that returns a fallback route or component.
  • Retry once. Many failures are temporary network problems. More than one retry usually only makes the user wait.
  • Show a useful fallback. Say that this area is unavailable, offer a retry button and keep the navigation working. The rest of the product must stay usable.

The manifest that lists the remotes deserves the same care. If the host fetches it at startup and the request fails, nothing loads. Bundle a last-known-good copy with the host, or serve the manifest from the same origin and cache as the host itself.

Timeouts

A dynamic import has no timeout. A request that hangs keeps the user in front of a spinner. Wrap the load in a race against a timer, and show the fallback when the timer wins. Count every timeout as a load failure in your metrics.

Stale chunks after a deploy

A user who opened the app yesterday still holds references to yesterday's files. If a deploy deletes them, the next lazy load fails. Two habits avoid this:

  1. Keep previous versions of each remote on the CDN for a period after each release. Files with a content hash in the name can live side by side.
  2. When a chunk fails to load, fetch the manifest again and retry before giving up.

Runtime errors: a boundary per area

React has error boundaries. Angular has no direct equivalent, so the boundary is built from other pieces:

  • A custom ErrorHandler in each remote that reports the error with the remote's name and version, and tells the host that this area failed.
  • A wrapper in the host around each mounted area. When an area reports a fatal error, the host replaces its content with the fallback and leaves the shell untouched.
  • Guarded mounting. If remotes are mounted as custom elements or through a mount function, wrap the call in a try/catch. A remote that throws while starting should never stop the host's own startup.

The shell must not depend on any remote to start. If the navigation, the session or the layout imports code from a remote, a failure in that remote becomes a failure of everything. More in the micro-frontend host shell.

Monitoring per remote

You cannot fix what you cannot attribute. Every error and every metric should carry the name and version of the remote that produced it.

  • Tag errors with remote name, remote version and host version.
  • Count load failures and timeouts per remote. A rise right after a deploy points to that release.
  • Route alerts to the owning team. An alert that goes to everyone is read by nobody.
  • Check remote entries from outside. A synthetic check that requests each remote entry URL every few minutes finds an outage before users do.

Fast rollback

When a release breaks an area, the fastest fix is to point the manifest back to the previous version. That only works if the previous files still exist and the manifest can change without rebuilding the host. Both are pipeline decisions, described in CI/CD for micro-frontends.

Test the failure paths. Block one remote entry in the browser's network tools and watch what happens. If the shell survives, the fallback appears and an alert reaches the right team, your isolation is real. See testing micro-frontends.

More in this section

Planning a migration or a micro-frontend platform?

In a 20-minute call you describe your situation and I tell you how I'd approach it. If it isn't worth doing yet, I'll say so.

Message me on LinkedIn