Keeping one look across micro-frontends: tokens, components and style isolation
Users do not know your product is built by five teams, and they should never find out from the buttons. A shared design system is what keeps independent teams producing one product.
Why it comes first
In a single application, visual consistency happens partly by accident. Everyone copies from the same code. Once teams ship separately, that accident stops. Each team solves the same problems in slightly different ways, and within a year the product looks like several products.
A design system is the countermeasure. It is also a precondition: starting micro-frontends without one means paying for it later, with a redesign on top.
Three layers
Design tokens
Tokens are named values: colors, spacing, typography, radii, shadows, z-index levels. Delivered as CSS custom properties, they work in every framework and inside Shadow DOM.
:root {
--color-primary: #0b5fff;
--space-2: 8px;
--radius-md: 6px;
}
The host loads the tokens once. A rebrand or a dark theme is then a change of token values, visible in every remote at the same moment.
Component library
Buttons, inputs, tables, dialogs and the other building blocks, built on the tokens. On an all-Angular platform this is an Angular library. On a multi-framework platform the options are web components, or tokens plus plain CSS with a thin implementation per framework.
Patterns and guidelines
How a form validates, what an empty state looks like, how errors are worded, how a page is laid out. These live in documentation with live examples. Storybook is a common tool for this.
Shared at runtime or bundled per remote
| Shared as a runtime singleton | Bundled in each remote | |
|---|---|---|
| Consistency | Every remote shows the same version | Remotes can differ until each one upgrades |
| Upgrades | One rollout; a breaking change affects everyone at once | Each team upgrades on its own schedule |
| Bundle size | One copy | Duplicated code |
| Main risk | Large blast radius | Visual drift |
A practical middle ground:
- Tokens always come from the host at runtime.
- The component library is shared as a singleton within one major version. Teams take minor versions freely.
- Major versions are adopted inside an agreed window. During that window two majors may coexist, each remote bundling its own.
The mechanics of sharing are in Shared dependencies and versions.
Versioning the design system
- Follow semantic versioning strictly. Removing an input, renaming a token or changing a component's size is a breaking change.
- Deprecate before removing. A deprecated component stays for at least one major version, with a warning and a documented replacement.
- Support a limited number of majors. Current and previous is a common rule. Older ones get no fixes.
Avoiding style leaks
With runtime federation all remotes share one document, so CSS from one can reach another. The usual sources:
- Global element selectors. A remote that styles
buttonorh1globally restyles the whole product. Only the design system defines base styles. - Disabled encapsulation. Angular scopes component styles by default.
ViewEncapsulation.Noneand::ng-deepare the usual escape routes. Flag them in review or with a lint rule. - Third-party global CSS. A remote that imports a full CSS framework affects everyone. Forbid it, or scope it under the remote's root class.
- Overlays. Dialogs, menus and tooltips often render in a container at the end of the document, outside the remote's own DOM subtree. Use the design system's overlay components, and share the underlying library as a singleton so there is only one container.
- Stacking order. Define z-index levels as tokens. Arbitrary values in remotes lead to dialogs hidden behind headers.
For remotes wrapped as web components, Shadow DOM gives strong style isolation. Custom properties pass through the shadow boundary, which is why tokens work well there.
Governance
- An owner. A small design system team, or the platform team together with a designer.
- A contribution model. Feature teams propose and build components, and the owners review them. Without this, the design system team becomes a bottleneck and teams build local variants.
- A promotion rule. A component needed by two teams moves into the library.
- Visual regression tests in the library, so a change to a button is seen before five teams discover it. Testing of the composed product is covered in Testing micro-frontends.
The common failure is a design system that is too slow to contribute to. Teams under deadline copy a component, change it locally and never come back.
Checklist
- Are tokens loaded once, by the host?
- Is the component library a shared singleton with a version policy?
- Is there a lint rule or review check for global selectors and disabled encapsulation?
- Do you know which design system version each remote runs today?
More in this section
- CI/CD for micro-frontends: independent pipelines, discovery and rollbacks
- Error isolation and resilience in micro-frontends
- Micro-frontend performance: the costs and how to control them
- Testing micro-frontends: a practical strategy
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