skip to content

In a microfrontends architecture, what is the core difference between integrating a microfrontend at build time versus at runtime?

level: juniorimportance: must knowfreq 70%

answer

  1. one artifact vs many bundles
  2. compile-time glue vs browser-time glue
  3. npm import vs script tag/manifest
  4. shared deploy vs independent deploy

basics

~20 s

Build-time means you bake all the pieces together into one app before you ship it, like baking ingredients into one cake. Runtime means the browser loads separate pieces live, like assembling a meal from dishes served at the table.

solid answer

~40 s

Build-time integration compiles/bundles a microfrontend's code into the host application during the CI build — e.g. as an npm package or via a monorepo import — producing one deployable artifact. Runtime integration keeps each microfrontend as a separately deployed bundle that the host fetches and executes in the browser at load time, via dynamic script tags, an import map, or a module-federation host/remote setup. The practical difference: build-time coupling means every microfrontend release requires the host to rebuild and redeploy; runtime integration lets each team deploy independently, with the host simply pointing at whatever version is live. That independence is exactly why microfrontends were invented, but it costs compile-time type safety and shifts a class of bugs to production.

go deeper

for a junior

Can state the one-line difference (bundled together vs loaded separately) and give one example mechanism for each side (npm import vs script tag).

for a middle

Explains why the difference matters operationally — who has to redeploy when, and what CI pipeline shape each implies.

for a senior

Can map the choice to team topology and org constraints, and name concrete tech for each (module federation, import maps, npm workspaces) with their trade-offs.

for a principal

Frames it as a build-vs-buy-style coupling decision at the organizational level, and can argue for a hybrid boundary strategy tied to how independently teams need to ship.

## What build-time integration means Build-time integration means a microfrontend's source code, or a compiled form of it, becomes part of the host application's own build pipeline and ends up in a single deployable artifact. The two common mechanisms are: 1. **Publishing the microfrontend as a versioned npm package** that the host lists as a dependency and installs. 2. **Placing the microfrontend directly inside a monorepo** that the host imports via a workspace path. Either way, a bundler such as **Webpack**, **esbuild**, or **Vite** traces the import graph at compile time and emits one JavaScript bundle (or a small, host-controlled set of chunks). The browser never independently requests the microfrontend's code; it is already inlined into whatever the host shipped. ## What runtime integration means Runtime integration keeps each microfrontend as its own independently built and independently deployed set of files, discovered by the host through a URL rather than an import statement resolved at compile time. - **Webpack Module Federation** (and its Rspack/Vite equivalents) is the most common mechanism today: the host declares a `remotes` map pointing at a manifest file the remote publishes, and at some point during page load — often lazily, when a route needs it — the host fetches that manifest, negotiates shared dependencies, and dynamically imports the remote's real code. - **Simpler variants** use native browser import maps or plain dynamic `<script>` tags pointing at a versioned URL. In every case, the defining trait is that the browser makes a live network request for code the host's own build never contained. ## The trade-off The reason this split exists is a genuine trade-off between two things teams want simultaneously and can't fully have at once: compile-time safety and deploy independence. - **Build-time integration** gives you a single artifact to test, version, and reason about — TypeScript can check that a microfrontend's exported component matches what the host expects, and the bundler can dedupe shared libraries precisely. The cost is that every team's release rides on the host's own build-test-deploy pipeline, so release cadence is shared. - **Runtime integration** flips this: each team ships on its own schedule, completely decoupled from the host's release train, but nothing checks at compile time that a remote's exposed API still matches what the host expects, and dependency versions have to be reconciled live in the browser instead of by a bundler ahead of time. ## Failure modes Failure modes differ accordingly. | Style | When they surface | The catch | |---|---|---| | Build-time integration's failures | show up early and cheaply — a broken import fails a PR build, a type mismatch fails `tsc` | but they can block unrelated teams whenever the shared pipeline breaks | | Runtime integration's failures | show up late and expensively — in production, as a user-facing incident | because there's no compiler standing between a breaking change in one team's code and a user hitting it | A remote that renames an exported prop, or a remote that requires a newer version of a 'shared, singleton' library than the host provides, will not fail anyone's build; it will fail in a live browser, often intermittently, and has to be caught by monitoring, contract tests, or manual QA instead. ## Where it shows up A concrete real-world illustration: a company like **IKEA** or **Zalando** publishing shared component libraries as versioned npm packages that product teams import and bundle is build-time integration, even inside a broader system loosely called 'microfrontends' — a fix only reaches users once each consuming team bumps the version and redeploys. By contrast, platforms like **Spotify's** desktop client and **DAZN's** frontend, which are publicly documented as adopting Module Federation, moved to runtime integration specifically once they had enough independently-owned frontend teams that a shared build-time release train became a bottleneck. Neither style is universally correct; the choice trades organizational deploy independence against compile-time correctness, and mature systems often use both styles for different boundaries within the same product, build-time for tightly coupled pieces, runtime for loosely coupled, independently-owned feature areas.

  • If a team wants the fastest possible feedback loop with full type-checking, which integration style should they lean toward, and why?
    Build-time integration, because importing a microfrontend as an npm package or monorepo module lets the compiler catch prop-shape and API mismatches before anything ships, and bundlers can tree-shake shared code across the boundary. The cost is that the host must rebuild and redeploy whenever any microfrontend changes, trading deploy independence for compile-time safety.
  • Can a team mix both styles in the same product?
    Yes — it's common to build-time-integrate rarely-changing, tightly coupled pieces like a shared header library while runtime-integrating independently owned feature areas like checkout versus a product catalog via module federation. The choice is per-boundary based on how often it changes and how much independence teams actually need.

Build-time integration is like baking a layer cake — once it's in the oven, the layers are one object. Runtime integration is like a buffet — each dish is prepared and plated separately, and diners (browsers) assemble their own plate from whatever dishes happen to be on the table at that moment.

saying these in an interview costs you the question

  • says microfrontends always means multiple git repos
  • conflates 'runtime integration' with iframes as the only mechanism
  • thinks build-time integration is inherently wrong for microfrontends
  • can't say what artifact actually changes at deploy time for each style

context