PATTERN Cited by 1 source
Shared UI-kit as internal npm package¶
Problem¶
In a micro-frontend deployment, each remote is owned by a different team. If every team re-creates primitive UI components (buttons, modals, inputs, typography, form controls), three things happen:
- Design drift. Buttons look and behave subtly different across remotes; the portal feels like N stitched applications, not one product.
- Duplicated work. Every new team's first sprint is "build a button".
- Design updates are O(N). Changing the primary-button hover state means N pull requests across N repos.
Solution¶
Publish a shared UI-kit as an internal npm package. The kit contains reusable components — buttons, modals, inputs, typography, layout primitives — along with design tokens (colours, spacing, typography scale). Every remote depends on the same package version; design updates flow out by bumping a single dependency across remotes.
The package is typically:
- Internal — published to a private npm registry or a monorepo workspace, not to public npm.
- Versioned semantically — patch/minor/major discipline so remotes can opt into risky changes.
- Owned by a design-system / platform team — not any one feature team.
- Peer-dependent on React / React-DOM — shared as a singleton across host + remotes (see concepts/shared-singleton-dependency).
In a Module-Federation deployment the UI-kit is usually bundled into each remote (static-linked via npm), not shared at runtime via Module Federation. The runtime-shared libraries are the heavy stateful ones (React, state management), not small composable UI primitives.
Trade-offs¶
Pro - One design language. Visual + behavioural consistency across remotes without per-team re-implementation. - Cheap design updates. Central change propagates via dependency bump. - Faster team onboarding. New teams don't rebuild primitives. - Common accessibility story. Button / modal focus trap / ARIA semantics are implemented once.
Con - Version skew. Remotes on different kit versions can render visually divergent screens simultaneously; the design team must manage coordinated upgrades for major changes. - Platform-team bottleneck. Feature teams wanting a new primitive go through the UI-kit team's roadmap. - Bundle-size repetition. Each remote bundles its own copy of the UI-kit — duplicated code across federation boundaries unless the kit is also marked as a shared library in Module Federation config. - Does not solve composite pages. Shared primitives compose into screen-level layouts; that layer still needs coordination (or it drifts again at a higher altitude).
Relation to broader design-system patterns¶
Sibling pattern: patterns/design-system-component-library-cross-platform — the same idea generalised across web + iOS + Android (e.g. Yelp CHAOS, Zalando Appcraft). The internal-npm variant is the web-only instance, typically sufficient for a browser-altitude micro-frontend deployment.
Seen in¶
- sources/2024-10-16-zalando-building-a-modular-portal-with-webpack-module-federation — canonical wiki instance. Zalando's Logistics Portal publishes "a shared UI-kit library … packaged as an internal npm module and distributed across all teams. It provides a set of reusable components, such as buttons, modals, input fields, and typography, all following the same design language and style guidelines." The team's own framing of the value: "any design updates could be applied centrally within the UI-kit and propagated across all applications, ensuring the portal always maintained a cohesive and up-to-date look and feel." 11 apps / 4 teams share one UI-kit.
Related¶
- concepts/micro-frontends — the architecture class this pattern stabilises.
- patterns/design-system-component-library-cross-platform — multi-platform generalisation of this pattern.
- concepts/module-federation-host-remote — the deployment topology the UI-kit is shared across.
- systems/webpack-module-federation — the runtime sharing mechanism for UI-kit is optional; static-link per remote is the common choice.
- systems/zalando-logistics-portal — canonical wiki deployment.