The micro-frontend host: what it is responsible for and what it must not do
The host is the first application the browser loads and the one piece every team depends on. Keeping it small is the most important design decision in a micro-frontend platform.
The host in one sentence
The host, also called the shell, owns what is common to the whole product and loads everything else on demand.
It is loaded on every visit, and every remote runs inside it. A mistake in the host affects all teams at once. That is the reason for both lists below.
What the host is responsible for
Top-level routing
The host maps URL prefixes to remotes. /billing/... belongs to the billing remote, /catalog/... to catalog. The host knows the prefix and nothing about the routes inside it. Details are in Routing across micro-frontends.
Login and session
The host starts the login flow, keeps the session and exposes the current user to the remotes. Remotes consume the session and never create one. See Shared authentication.
Layout
The header, the main navigation, the footer and the content area where the active remote renders. Product-wide controls live here too: the language selector, the theme, global notifications.
Loading remotes
The host knows where each remote lives, normally through a manifest fetched at startup. It loads a remote when its route is first visited and shows a loading state in the meantime.
Fallback
Remotes sometimes fail to load. The host decides what the user sees in that case: an error panel in the content area, a retry action, and navigation that keeps working so the user can go elsewhere.
In Angular, loading a remote is a promise inside a lazy route, so a fallback can be a catch that returns local routes:
{
path: 'billing',
loadChildren: () =>
loadRemoteModule('billing', './routes')
.then(m => m.BILLING_ROUTES)
.catch(() => REMOTE_UNAVAILABLE_ROUTES)
}
Cross-cutting plumbing
The global error handler, telemetry setup, feature flag bootstrap and locale. These are initialized once and offered to remotes through shared packages.
What the host must not do
- Contain business logic. No domain screens and no API calls about invoices or orders. A dashboard that mixes data from several areas is itself a remote with an owner.
- Know the internals of a remote. No imports of remote types, no knowledge of internal routes, no special cases per remote in the code.
- Act as the shared library. Utilities belong in versioned packages. When remotes import helpers from the host, every remote depends on the host's release cycle.
- Hold feature state. Cart contents, filters and form drafts belong to the remote that owns them, or to the backend.
- Require a release to add or update a remote. Remote locations and menu entries come from configuration read at runtime.
- Grow heavy. Every kilobyte in the host is paid on every page of the product.
A simple test: if a feature team needs a change in the host to ship a normal feature, the host is doing too much. Host changes should be rare, and most of them should be platform work.
The contract the host offers
Remotes need a few things from the host. Write them down and version them like an API.
| Contract | Typical form |
|---|---|
| Mount point | A route prefix and a content area |
| Current user and token | A shared auth service or a small function from a platform package |
| Navigation | Standard URLs and the shared router |
| Menu entries | Declared by each remote in the manifest or configuration; rendered by the host |
| Global events | A short list of named events, such as user changed or language changed |
| Design system | A supported version range of tokens and components |
Anything outside this contract is private to the host. Remotes that reach into the host's DOM or internal services will break on the next host release, and the host team is right to let them.
Who owns the host
A small platform team. The host changes less often than any remote, and its changes get stricter review, because the blast radius is the whole product. Its pipeline should include a smoke test that loads every remote before a release is promoted.
Feature teams contribute to the host through the platform team, the way they would contribute to any shared library. Team structure is discussed in Team ownership and Conway's law.
Checklist
- Can a new remote be added without rebuilding the host?
- Does the product stay usable when one remote fails to load?
- Is there any business API call in the host? If so, move it.
- Is the contract between host and remotes written down and versioned?
- Does every host release run a smoke test against all remotes?
- Is the host's bundle size tracked over time?
More in this section
- Routing across micro-frontends: route ownership, deep links and the navigation contract
- Sharing login and session across micro-frontends
- How micro-frontends communicate, and what to avoid
- Shared dependencies and versions in micro-frontends
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