FynMesh

Legacy RequireJS micro frontends on federated React

Micro frontends that load through RequireJS can get their shared libraries from Module Federation, without being rebuilt. The guide explains the setup.

The setup

Before Module Federation, many teams built micro frontends with webpack as AMD bundles loaded by RequireJS. Shared libraries like React and the UI kit are webpack externals. The page loads one copy of each, and every bundle asks for them with define(["react", "react-dom", "ui-kit"], ...).

The problem

Every widget is locked to the library versions the legacy CWP provides. Any upgrade needs every team that builds on the CWP to coordinate. Module Federation solves version sharing, but it cannot load these AMD bundles. A large codebase cannot drop its legacy code in one shot, so there is no path from here to federation.

The CWP as a FynApp

The common web package (CWP) becomes a FynApp. It installs React and the UI kit from npm at pinned versions. It serves them from federation, under the AMD ids the bundles already ask for, and a kernel add-on routes RequireJS to it. Each RequireJS context stays on the old common bundle or moves to the CWP, so widgets move to a new React major in stages, with no rebuild. New FynApps share the CWP's React when their range matches, or load their own. Legacy widgets and FynApps run on the same page, so the codebase moves to federation one piece at a time.

Before Team A, B, C bundleswebpack AMD define("react", "ui-kit") → Common bundleReact 18 and ui-kit, one copy for all
With the CWP Team A, B, C bundlessame files, not rebuilt → AMD add-onreads the CWP's amd-meta.js → CWP FynAppCWP 3: React 18.3.1, CWP 4: React 19.2.8, ui-kit 1.4.0 ← New FynAppsshare it, or bring another major

Try it

  1. Pick the federated CWP release, then pick Legacy CWP or Federated CWP for each set. Each set is its own RequireJS context with the same widget bundles, which were built against React 18. The legacy CWP is the old setup: UMD React 18 files and legacy-components/dist/ui-kit.js. CWP 3 and CWP 4 serve React 18 or React 19 and ui-kit from federation, as the Files fetched table shows.
  2. Load Team C in a set. RequireJS fetches only widget-c.js and reuses the React that set already loaded.
  3. Check the React instances table. Each row is one copy of React, the apps that use it, and how many times its file was fetched. Two federated sets share one copy. Two legacy sets get one copy each.
The federated CWP release. A page runs one, and every federated set uses it.

Set 1: unchanged webpack AMD bundles

Team C is not loaded yet.

Set 2: unchanged webpack AMD bundles

Team C is not loaded yet.

FynApps on the same page

Two ordinary FynApps that import esm-react through federation. They know nothing about RequireJS or the legacy widgets.

Loads after the legacy widgets.
Loads after the legacy widgets.

React instances on this page

Reactloaded fromused byfiles fetched

Files fetched

atsetkindfile

Dependency graph

Set 1

Set 2

AMD add-on metrics

amd.* entries from kernel telemetry. They are the input for generating preload meta later.

entrysetidroutedepsmsurl