<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: MFEOrchestrator</title>
    <description>The latest articles on DEV Community by MFEOrchestrator (@mfeorchestrator).</description>
    <link>https://dev.to/mfeorchestrator</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4170607%2F4555c471-0bc2-41f6-b34e-ca1f31ba9af3.png</url>
      <title>DEV Community: MFEOrchestrator</title>
      <link>https://dev.to/mfeorchestrator</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mfeorchestrator"/>
    <language>en</language>
    <item>
      <title>One build, every environment: runtime configuration for micro frontends</title>
      <dc:creator>MFEOrchestrator</dc:creator>
      <pubDate>Thu, 08 Oct 2026 08:10:13 +0000</pubDate>
      <link>https://dev.to/mfeorchestrator/one-build-every-environment-runtime-configuration-for-micro-frontends-58j6</link>
      <guid>https://dev.to/mfeorchestrator/one-build-every-environment-runtime-configuration-for-micro-frontends-58j6</guid>
      <description>&lt;p&gt;Look at your pipeline. If it builds staging and production separately from the same commit, you are shipping an artifact nobody tested. You tested the staging one.&lt;/p&gt;

&lt;p&gt;Most of the time this is fine, right up until the day it is not — a variable spelled differently in one environment, a flag that defaulted the other way, a bundle that behaved because of something only the staging build had. The bug appears in production only, and the investigation starts with the least useful sentence in software: it works on staging.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why does each environment get its own build?
&lt;/h2&gt;

&lt;p&gt;Because the configuration is inside the bundle. Somewhere in the code there is an API base URL, a feature flag, a tenant id, and at build time a bundler replaced it with a literal string. Change the value, and you have changed the bundle, so you build again.&lt;/p&gt;

&lt;p&gt;For a single application this is merely wasteful. For micro frontends it compounds: every micro frontend, times every environment. Five micro frontends and three environments is fifteen builds of code that was identical in all fifteen.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does it actually cost?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The test result stops transferring.&lt;/strong&gt; Whatever CI proved about the staging artifact, it proved about that artifact. The production one was built later, separately, from configuration nobody exercised.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Promotion becomes a rebuild.&lt;/strong&gt; Moving a version from staging to production is not a promotion any more, it is a new build — with a new chance to fail, on the day you least want one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rollback gets slower.&lt;/strong&gt; The old artifact for this environment may not exist any more. If it does not, rolling back means building it again, which means the rollback is a deploy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration drifts silently.&lt;/strong&gt; Three sets of environment variables in three places, and no single view of what actually differs. The drift is invisible until it is an incident.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What does runtime configuration actually mean?
&lt;/h2&gt;

&lt;p&gt;It means the bundle contains no environment-specific value at all. Instead, on startup, the application asks for them and gets back a small document — a plain JSON object with the API base URL, the flags, whatever else differs.&lt;/p&gt;

&lt;p&gt;The bundle is then genuinely identical everywhere. The same file, the same hash, the same artifact that CI tested, served to staging and production alike. What differs between environments is one document, and that document is data rather than code.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does the browser get the configuration?
&lt;/h2&gt;

&lt;p&gt;The host fetches it before it mounts anything. In practice this is one request early in the boot sequence, its result handed to whatever the application uses for configuration, and only then does rendering start.&lt;/p&gt;

&lt;p&gt;Two details are worth getting right. Keep the response small, because it sits on the critical path of the first paint. And keep the cache short — a configuration cached for an hour at the edge is a configuration you cannot change for an hour, which quietly undoes the point.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about secrets?
&lt;/h2&gt;

&lt;p&gt;There are none here. Anything the browser can read is public, whether it arrived in a bundle or a JSON document: a value shipped to a client is a published value. Runtime configuration changes when a value is decided, not who can see it.&lt;/p&gt;

&lt;p&gt;What belongs in it is the non-secret configuration that varies: base URLs, public keys, feature flags, tenant identifiers. Anything genuinely secret stays on a server that never hands it to a browser, exactly as before.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does this work with Vite and Webpack?
&lt;/h2&gt;

&lt;p&gt;Yes, and the change is the same shape in both, because it is not really a bundler change. You stop reading &lt;code&gt;import.meta.env&lt;/code&gt; or &lt;code&gt;process.env&lt;/code&gt; at module scope and start reading a value that was fetched. The bundler stops being involved the moment the value is no longer inlined.&lt;/p&gt;

&lt;p&gt;The one thing that does stay at build time is the set of remote &lt;strong&gt;names&lt;/strong&gt; in a Module Federation setup. Names are structural. The URLs behind them are not, and those can come from the same document as everything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does this have to do with rollback?
&lt;/h2&gt;

&lt;p&gt;Everything, and it is the same mechanism. Once an environment is described by a document rather than by a build, changing what an environment serves is a write, not a deploy. That is what makes a &lt;a href="https://mfe-orchestrator.dev/blog/roll-back-a-micro-frontend-in-30-seconds" rel="noopener noreferrer"&gt;thirty-second rollback&lt;/a&gt; possible, and it is why the two are worth doing together: one build for every environment is the thing that makes the old artifacts still exist when you need them.&lt;/p&gt;

&lt;p&gt;Build once, test that one, run it everywhere. The configuration is the only thing that was ever environment-specific — so it should be the only thing that varies.&lt;/p&gt;

</description>
      <category>microfrontends</category>
      <category>devops</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>How to Ship Canary Releases for Microfrontends Without Losing Your Mind</title>
      <dc:creator>MFEOrchestrator</dc:creator>
      <pubDate>Thu, 08 Oct 2026 08:10:09 +0000</pubDate>
      <link>https://dev.to/mfeorchestrator/how-to-ship-canary-releases-for-microfrontends-without-losing-your-mind-28pb</link>
      <guid>https://dev.to/mfeorchestrator/how-to-ship-canary-releases-for-microfrontends-without-losing-your-mind-28pb</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Canary releases let you test new microfrontend versions on a slice of your traffic before going full rollout. Most teams build custom tooling for this. You don't have to.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem With Shipping Microfrontend Updates
&lt;/h2&gt;

&lt;p&gt;You've just merged a feature to your microfrontend. It's tested locally, it passed CI. Now what?&lt;/p&gt;

&lt;p&gt;In monolithic architectures, you'd just deploy and move on. But with microfrontends, you're running multiple independently-deployed remotes feeding into a host application. Each one can fail independently. And unlike a full-app rollout, you can't easily A/B test a new MFE version before pushing it live to everyone.&lt;/p&gt;

&lt;p&gt;So most teams end up building their own solution:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Custom feature flags&lt;/strong&gt; that toggle versions per user (adds complexity to your MFE code)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual traffic splitting logic&lt;/strong&gt; (now you're maintaining deployment state)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sticky session routing&lt;/strong&gt; (sessions need to stick to the same MFE version, otherwise users jump between old and new)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring and rollback procedures&lt;/strong&gt; (when things go wrong at 2 AM, you need a fast way out)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's operational debt masquerading as a deployment strategy.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is a Canary Release, Anyway?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;canary release&lt;/strong&gt; is a progressive rollout pattern: instead of flipping a switch and serving the new version to everyone, you start by serving it to a small percentage of your traffic (5–10%), then gradually increase that percentage as you confirm it's stable.&lt;/p&gt;

&lt;p&gt;The name comes from mining: canaries were sent into mines as an early warning system. Same idea—your early users are the canary. If they have problems, you catch them before the entire flock is affected.&lt;/p&gt;

&lt;h3&gt;
  
  
  Canary vs. Other Deployment Strategies
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Strategy&lt;/th&gt;
&lt;th&gt;What happens&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Blue-green&lt;/td&gt;
&lt;td&gt;Two identical production environments; you flip traffic from one to the other&lt;/td&gt;
&lt;td&gt;Zero-downtime deployments; rollbacks are instant&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rolling update&lt;/td&gt;
&lt;td&gt;Gradually replace old instances with new ones&lt;/td&gt;
&lt;td&gt;Stateless services; works fine in containers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Canary release&lt;/td&gt;
&lt;td&gt;Route a percentage of traffic to the new version; increase % over time&lt;/td&gt;
&lt;td&gt;Testing new features safely; catching runtime errors early&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Feature flags&lt;/td&gt;
&lt;td&gt;Toggle features on/off at runtime; doesn't change the deployed version&lt;/td&gt;
&lt;td&gt;A/B testing; feature experiments; gradual enablement&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why Canary Releases Are Harder for Microfrontends
&lt;/h2&gt;

&lt;p&gt;Three reasons:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Traffic Routing is Complex&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In a traditional app, you control the load balancer. Route 10% of requests to the new version, boom, done.&lt;/p&gt;

&lt;p&gt;With microfrontends, your host application doesn't know (and shouldn't need to know) which version of each remote it's loading. The host just asks for the MFE, and some service returns a URL. If you want different users to get different versions, you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sticky session management (so the same user always gets the same version across multiple page views)&lt;/li&gt;
&lt;li&gt;Per-microfrontend decision-making (you might canary version 2.1 of the checkout MFE while keeping the header MFE at 1.0)&lt;/li&gt;
&lt;li&gt;Server-side traffic splitting logic (handled entirely server-side; the host page shouldn't be aware of the split)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Versioning is Invisible&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In monolith-land, a deploy is a deploy. You know exactly what version is running.&lt;/p&gt;

&lt;p&gt;With MFEs, multiple versions might be running simultaneously, and users won't notice the transition. If a user's session spans a canary increase (e.g., they were at 5% when they loaded the page, then 10% of new users got the new version), they might end up on different versions mid-session if you're not careful.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Rollback Must Be Instant&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If a canary goes bad, you need to stop the bleeding immediately. Rolling back a traditional deployment means re-running CI/CD or reverting to a previous Docker image. That's 5–15 minutes.&lt;/p&gt;

&lt;p&gt;With microfrontends, users might cache the new version. You need a way to instantly point all canary traffic back to the stable version—without re-deploying anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Traditional DIY Approach (What You're Probably Doing)
&lt;/h2&gt;

&lt;p&gt;Here's what most teams build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Pseudo-code: your custom canary logic
if user.id % 100 &amp;lt; canary_percentage:
  serve(mfe_version_new)
else:
  serve(mfe_version_stable)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A database table tracking &lt;code&gt;canary_percentage&lt;/code&gt;, &lt;code&gt;start_time&lt;/code&gt;, &lt;code&gt;version_new&lt;/code&gt;, &lt;code&gt;version_stable&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A dashboard UI to adjust the percentage&lt;/li&gt;
&lt;li&gt;Webhooks to trigger when the canary percentage changes&lt;/li&gt;
&lt;li&gt;Metrics/logging to track how the canary is performing&lt;/li&gt;
&lt;li&gt;Runbooks for what to do if the canary fails&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cost&lt;/strong&gt;: 2–3 weeks of development. Ongoing maintenance: 30% of one engineer's time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Better Way: Native Canary Releases
&lt;/h2&gt;

&lt;p&gt;A better approach is to build canary releases into your MFE orchestration layer—the service that decides which version each user gets.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxo1x7l7b5asux4gm4n9z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxo1x7l7b5asux4gm4n9z.png" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's what that looks like:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Enable Canary for a Microfrontend
&lt;/h3&gt;

&lt;p&gt;Open the microfrontend in your control panel. Under &lt;strong&gt;Release&lt;/strong&gt;, you'll see &lt;strong&gt;Canary Settings&lt;/strong&gt;. Toggle it on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Configure the Canary
&lt;/h3&gt;

&lt;p&gt;You'll be asked for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Canary percentage -&lt;/strong&gt; What % of new users get the new version? 10%&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Canary type -&lt;/strong&gt; How do you want to split traffic? Sticky (per-user)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Canary version -&lt;/strong&gt; Which version is the canary? &lt;code&gt;1.2.0-beta&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment type -&lt;/strong&gt; Should the new version be deployed fresh, or just routed to? Use existing deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjtl7mcha9mqqt0tpvg1h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjtl7mcha9mqqt0tpvg1h.png" width="800" height="711"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Monitor
&lt;/h3&gt;

&lt;p&gt;Watch your metrics. Error rates, session duration, user feedback—whatever tells you if the canary is healthy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Increase the Percentage
&lt;/h3&gt;

&lt;p&gt;As confidence grows, increase the percentage. 10% → 25% → 50% → 100%.&lt;/p&gt;

&lt;p&gt;Or if something goes wrong: instant rollback. Flip the percentage back to 0%, and all traffic goes back to the stable version. No re-deploy. No cache-busting. Just a config change.&lt;/p&gt;

&lt;h2&gt;
  
  
  How MFE Orchestrator Handles This
&lt;/h2&gt;

&lt;p&gt;If you're using &lt;strong&gt;MFE Orchestrator&lt;/strong&gt;, canary releases are built in. Here's the workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Deploy a new version of your MFE.&lt;/strong&gt; Push to your repository; MFE Orchestrator detects the build and creates an immutable snapshot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enable canary in the UI.&lt;/strong&gt; One toggle. Four fields. That's it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Watch metrics.&lt;/strong&gt; The orchestrator captures deployment events and canary outcomes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Increase or rollback.&lt;/strong&gt; Adjust the percentage via the UI. Changes are instant; no CI/CD re-run required.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Why This Works
&lt;/h3&gt;

&lt;p&gt;MFE Orchestrator makes three bets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Immutable deployment snapshots&lt;/strong&gt;: Every version is locked in time. Rollback doesn't mean "re-run the build"; it means "point to a previous snapshot." Instant. ~30 seconds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server-side sticky assignment&lt;/strong&gt;: The decision about which version you get is made entirely server-side. The host page doesn't need to know or care. Sticky by default, so the same user always gets the same version within a session.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-microfrontend decisions&lt;/strong&gt;: You canary one MFE without affecting others. Checkout at 2.0, header at 1.5, and they work together seamlessly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step-by-Step Walkthrough: Setting Up Your First Canary
&lt;/h2&gt;

&lt;p&gt;Let's say you've deployed a new version of your &lt;code&gt;payment-mfe&lt;/code&gt; (v2.0). It's tested locally, but you want to be cautious before sending it to all 500K daily users.&lt;/p&gt;

&lt;h3&gt;
  
  
  Before You Start
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You have a stable version running (v1.5). Keep it as your baseline.&lt;/li&gt;
&lt;li&gt;You have a new version ready to test (v2.0). It's built, versioned, and deployed to your hosting.&lt;/li&gt;
&lt;li&gt;You're using an MFE orchestration layer (MFE Orchestrator, qiankun, single-spa + a custom control plane, etc.).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Walkthrough
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Navigate to your payment-mfe in the control panel.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Look for the &lt;strong&gt;Release&lt;/strong&gt; section. You'll see the current version (v1.5) and a &lt;strong&gt;Canary Settings&lt;/strong&gt; toggle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Enable Canary Settings.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Toggle the switch. A form appears asking for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Canary percentage&lt;/strong&gt;: Start small. 5%.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Canary type&lt;/strong&gt;: Choose "Sticky per-user" (same user always gets the same version).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Canary version&lt;/strong&gt;: Select v2.0.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment type&lt;/strong&gt;: "Use existing deployment" (v2.0 is already deployed).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Click Save.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The orchestrator immediately starts routing 5% of traffic to v2.0. The other 95% gets v1.5.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Deploy another version&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go to the deployment panel and hot Deploy button&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Monitor for the next 30 minutes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Watch your error logs, session analytics, and user feedback. Is v2.0 crashing? Are cart completions still happening? Any JavaScript errors in the console?&lt;/p&gt;

&lt;p&gt;If everything looks good: &lt;strong&gt;continue to Step 5&lt;/strong&gt;.&lt;br&gt;
If something breaks: &lt;strong&gt;immediately set canary percentage to 0%&lt;/strong&gt;. Rollback is instant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Increase the percentage.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After 30 minutes of green metrics, bump the canary to 10%. Wait another 30 minutes. Then 25%. Then 50%.&lt;/p&gt;

&lt;p&gt;By the time you hit 100%, v2.0 is serving all traffic, and v1.5 is no longer in the critical path.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Turn off Canary Settings.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once you're at 100%, you can either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let the canary run indefinitely (keeps a fallback to v1.5 if v2.0 ever fails)&lt;/li&gt;
&lt;li&gt;Disable canary and make v2.0 the stable release&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common Pitfalls
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pitfall 1: Canary % Doesn't Add Up to 100%
&lt;/h3&gt;

&lt;p&gt;If your canary is at 10% and your stable version is at 90%, where do the other 0% go?&lt;/p&gt;

&lt;p&gt;They don't. The math always works out: if canary is at X%, stable is at (100 - X)%.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pitfall 2: Jumping to 100% Too Quickly
&lt;/h3&gt;

&lt;p&gt;It's tempting. Your canary looked good for 5 minutes. Ship it to everyone!&lt;/p&gt;

&lt;p&gt;Resist. Wait for real usage patterns. Weekday traffic looks different from weekends. Mobile usage differs from desktop. Edge cases take time to appear.&lt;/p&gt;

&lt;p&gt;Recommendation: &lt;strong&gt;Increase by 1-2x every 30–60 minutes&lt;/strong&gt;, depending on your traffic volume.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pitfall 3: Not Monitoring the Right Metrics
&lt;/h3&gt;

&lt;p&gt;Canary health isn't just about "no errors." Also watch:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Error rate&lt;/strong&gt;: Obvious, but watch for slow increases (not just crashes).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Response time&lt;/strong&gt;: Did v2.0 get slower?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User engagement&lt;/strong&gt;: Are users dropping off? Completing transactions?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browser console errors&lt;/strong&gt;: v2.0 might have script errors that don't crash but hurt UX.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pitfall 4: Forgetting to Test the Rollback Path
&lt;/h3&gt;

&lt;p&gt;You've decided canary is the way to go. But have you practiced rolling back? Setting percentage to 0% should be fast and painless. Do a drill.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Not to Use Canary Releases
&lt;/h2&gt;

&lt;p&gt;Canary releases are powerful, but they're not always the right choice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Breaking changes to your MFE contract&lt;/strong&gt;: If v2.0 changes how remotes communicate with the host, canary won't help. You'd need to coordinate a host deployment first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One-off hotfixes&lt;/strong&gt;: If you're patching a critical bug and need it live in 60 seconds, canary adds no value. Just deploy and monitor closely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For most feature updates and optimization work, though? Canary is your friend.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Payoff
&lt;/h2&gt;

&lt;p&gt;Here's what canary releases buy you:&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Catch bugs before they hit all users&lt;/strong&gt;&lt;br&gt;
✅ &lt;strong&gt;Roll back in seconds, not minutes&lt;/strong&gt;&lt;br&gt;
✅ &lt;strong&gt;Test real production traffic (not synthetic)&lt;/strong&gt;&lt;br&gt;
✅ &lt;strong&gt;Gradual confidence building&lt;/strong&gt;&lt;br&gt;
✅ &lt;strong&gt;Less stress&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That last one is underrated. Knowing you can safely test a new version on 5% of your users, then roll back with one click if something breaks—that's peace of mind.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR: The Canary Release Checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] You have a stable version (v1.5) running for all users.&lt;/li&gt;
&lt;li&gt;[ ] You have a new version (v2.0) built, tested, and deployed.&lt;/li&gt;
&lt;li&gt;[ ] You've enabled Canary Settings and set percentage to 5%.&lt;/li&gt;
&lt;li&gt;[ ] You've monitored error rates, response times, and user behavior for 30 minutes.&lt;/li&gt;
&lt;li&gt;[ ] You've increased percentage to 10%, then 25%, then 50%, waiting 30 minutes between each.&lt;/li&gt;
&lt;li&gt;[ ] At 100%, you've decided: keep the canary active (as a rollback safety net) or disable it.&lt;/li&gt;
&lt;li&gt;[ ] You've documented the rollout (when you increased %, what metrics you watched, any issues that came up).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;If you're doing this manually today&lt;/strong&gt;: You're probably maintaining custom feature flag logic, a dashboard to track canary %, and a runbook for rollbacks. That's fine—it works. But it's friction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you want to reduce that friction&lt;/strong&gt;: Look into an MFE orchestration layer that handles canary natively. MFE Orchestrator is one option. The benefit: canary releases become a 30-second UI interaction instead of a custom integration.&lt;/p&gt;

&lt;p&gt;Either way, canary releases are your best tool for safe, confident microfrontend deployments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://mfe-orchestrator.dev/documentation/docs/microfrontends/canary-releases/" rel="noopener noreferrer"&gt;MFE Orchestrator: Canary Releases Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.armory.io/deployment-patterns/" rel="noopener noreferrer"&gt;Progressive Delivery: Four Deployment Strategies&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>microfrontends</category>
      <category>devops</category>
      <category>frontend</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Deterministic AI Agents in Mission-Critical Systems: Why Microfrontend Boundaries Matter</title>
      <dc:creator>MFEOrchestrator</dc:creator>
      <pubDate>Thu, 08 Oct 2026 08:10:04 +0000</pubDate>
      <link>https://dev.to/mfeorchestrator/deterministic-ai-agents-in-mission-critical-systems-why-microfrontend-boundaries-matter-16f9</link>
      <guid>https://dev.to/mfeorchestrator/deterministic-ai-agents-in-mission-critical-systems-why-microfrontend-boundaries-matter-16f9</guid>
      <description>&lt;p&gt;You've deployed an LLM agent to production to automate customer workflows. It's trained on your entire codebase, your entire state tree, your entire API surface. It works. Then it doesn't. It hallucinated a payment endpoint. It mutated shared state. The entire system broke.&lt;/p&gt;

&lt;p&gt;Now imagine the same agent, but it can only see—and touch—a single bounded domain: the checkout flow. Same intelligence. Zero blast radius.&lt;/p&gt;

&lt;p&gt;That's what microfrontend boundaries do for AI reliability.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Determinism Problem: Why AI + Mission-Critical = Danger
&lt;/h2&gt;

&lt;p&gt;Mission-critical systems live on a knife's edge. A payment system cannot fail. A healthcare workflow cannot guess. A financial settlement engine cannot hallucinate. These systems run monoliths or tightly-coupled architectures because the engineers who built them needed &lt;em&gt;predictability&lt;/em&gt;—the certainty that, given X input, you get Y output, and nothing breaks state elsewhere.&lt;/p&gt;

&lt;p&gt;Then we introduced LLM agents.&lt;/p&gt;

&lt;p&gt;The promise is seductive: deploy an intelligent agent to automate entire business processes. Let it read your API docs, understand your domain, make decisions. But here's what actually happens:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;State explosion.&lt;/strong&gt; Your agent sees the entire application state tree. It has access to every domain, every service, every possible side effect. The surface area for error isn't just the agent's logic—it's the agent's logic multiplied by the complexity of your entire system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hallucination risk scales with scope.&lt;/strong&gt; The more context an agent has, the more ways it can misinterpret that context. It reads a deprecated API endpoint and decides it's the primary one. It confuses a state variable in Module A with the similar one in Module B. The system is now in a broken state, and your entire platform is down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blast radius = system blast radius.&lt;/strong&gt; If your agent goes wrong, and it can touch anything, it can break anything. Traditional unit tests and integration tests miss this because they test code, not agent decision-making under uncertainty. Your mission-critical system is now dependent on the stability of an AI model, not just your code.&lt;/p&gt;

&lt;p&gt;Mission-critical environments demand determinism. They demand predictability. They demand &lt;em&gt;architectural safety&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Unbounded AI Agent: Today's Default Pattern
&lt;/h2&gt;

&lt;p&gt;This is how most teams deploy AI agents today:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LLM Agent
    ↓
Full App Context (entire state tree, all APIs, all domains)
    ↓
Mission-Critical System (payment, auth, data warehouse, etc.)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why? It's easier to implement. A single agent with unrestricted context is simpler to build than a scoped, boundary-aware one. You write fewer prompts. You deal with fewer API contracts. And in the early phases, it works.&lt;/p&gt;

&lt;p&gt;Then you go to production.&lt;/p&gt;

&lt;p&gt;The agent starts making decisions based on patterns it learned from your entire codebase. It mutates state it wasn't supposed to touch. It triggers side effects in systems it didn't know existed. Your tests pass. Your deployment succeeds. And six hours later, customer transactions are failing silently.&lt;/p&gt;

&lt;p&gt;The real cost isn't the agent's intelligence—it's the agent's &lt;em&gt;reach&lt;/em&gt;. An intelligent system with access to your entire platform is more dangerous than a dumb system with the same access. Because it will find edge cases, race conditions, and state inconsistencies that humans never thought to test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Microfrontend Boundaries as AI Safety
&lt;/h2&gt;

&lt;p&gt;Here's what most teams don't realize: microfrontend architectures solve this problem by accident.&lt;/p&gt;

&lt;p&gt;In a microfrontend system, each frontend module is a bounded domain. It has its own state management. It has its own API surface. It has an explicit contract with the rest of the system. The module doesn't see global state. It doesn't call arbitrary endpoints. It operates within a defined perimeter.&lt;/p&gt;

&lt;p&gt;Now scope your AI agent to that same perimeter.&lt;/p&gt;

&lt;p&gt;An agent running inside the checkout MFE:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can only see checkout state&lt;/li&gt;
&lt;li&gt;Can only call checkout APIs&lt;/li&gt;
&lt;li&gt;Can only modify checkout flows&lt;/li&gt;
&lt;li&gt;If it breaks, it breaks checkout—not the entire system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's the pattern: &lt;strong&gt;agent boundary = MFE boundary.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The blast radius shrinks from "entire platform" to "single domain." Failure becomes containable. Recovery becomes predictable. Your mission-critical system survives.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monolith vs. MFE-Scoped Agent: The Safety Trade-off
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Monolith + Unbounded Agent&lt;/th&gt;
&lt;th&gt;MFE + Scoped Agent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Context Surface&lt;/td&gt;
&lt;td&gt;Entire system state + all APIs&lt;/td&gt;
&lt;td&gt;Low (limited context = fewer interpretations)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hallucination Risk&lt;/td&gt;
&lt;td&gt;High (misinterpreting global patterns)&lt;/td&gt;
&lt;td&gt;Low (limited context = fewer interpretations)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Blast Radius&lt;/td&gt;
&lt;td&gt;System failure&lt;/td&gt;
&lt;td&gt;Single MFE failure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rollback Scope&lt;/td&gt;
&lt;td&gt;Entire deployment&lt;/td&gt;
&lt;td&gt;Single MFE (instant)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Testing Determinism&lt;/td&gt;
&lt;td&gt;Hard (agent behavior influenced by global state)&lt;/td&gt;
&lt;td&gt;Easy (agent behavior bounded by MFE contract)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;On-call Wake-up Risk&lt;/td&gt;
&lt;td&gt;3 AM page for "agent broke everything"&lt;/td&gt;
&lt;td&gt;Page only if checkout is down&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The trade-off is real: you lose some agent flexibility. It can't orchestrate across five systems. But you gain something more valuable: &lt;strong&gt;operational predictability in mission-critical systems.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Determinism Through Architectural Isolation
&lt;/h2&gt;

&lt;p&gt;Bounded state isn't just safer—it's more predictable.&lt;/p&gt;

&lt;p&gt;When an agent's context is limited to a single MFE, its behavior becomes testable. You can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Enumerate the state space.&lt;/strong&gt; "What are all possible checkout states?" is answerable. "What are all possible system states?" is not.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Define the API contract.&lt;/strong&gt; "These are the three operations the agent can perform," not "the agent can call anything."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Predict failure modes.&lt;/strong&gt; You can reason about what happens when the agent misinterprets checkout data, because checkout data is bounded.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Determinism here means: given the same input, the same external conditions, and the same AI model, the agent will behave consistently. It won't have unexpected interactions with unrelated systems. It won't mutate state it wasn't supposed to touch.&lt;/p&gt;

&lt;p&gt;In mission-critical systems, determinism is survival.&lt;/p&gt;

&lt;p&gt;And when something does break—because it will—you can roll back instantly. Not the entire deployment. Not a ten-minute redeploy cycle. A single MFE, rolled back to the previous snapshot in 30 seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Infrastructure Layer: Deployment Reliability for AI
&lt;/h2&gt;

&lt;p&gt;But there's a prerequisite: your microfrontend architecture needs to support instant rollback and canary releases.&lt;/p&gt;

&lt;p&gt;This is where many teams fail. They have MFEs, but they can't deploy them independently. They can't roll back a single remote without touching the host application. They can't test a new agent version against 5% of users before the full rollout.&lt;/p&gt;

&lt;p&gt;When your agent needs to be deployed, tested, and potentially rolled back—in production—you need deployment infrastructure that understands MFE semantics. Infrastructure that treats each MFE as an independently deployable unit with its own release cycle.&lt;/p&gt;

&lt;p&gt;Orchestration of microfrontends isn't just about composition anymore. It's about supporting the operational requirements of AI-driven systems: rapid iteration, bounded scope, instant recovery.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Checklist: Making Your Agents Deterministic
&lt;/h2&gt;

&lt;p&gt;If you're running AI agents in a mission-critical environment, use this checklist:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Define agent scope = MFE boundary&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Which single MFE will the agent operate within?&lt;/li&gt;
&lt;li&gt;Does the agent's use case fit entirely inside that boundary?&lt;/li&gt;
&lt;li&gt;If no, reconsider scoping or multi-agent orchestration.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API contract = agent contract&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Document the exact APIs the agent can call (all of them)&lt;/li&gt;
&lt;li&gt;Document the exact state the agent can read (all of it)&lt;/li&gt;
&lt;li&gt;Make this contract explicit in prompts and system design&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State isolation validation&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Can the agent accidentally mutate state outside its MFE?&lt;/li&gt;
&lt;li&gt;Are there shared data structures it might corrupt?&lt;/li&gt;
&lt;li&gt;Test this explicitly; don't assume architectural isolation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring + rollback triggers&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Define what "agent went wrong" means for your domain (e.g., checkout completion rate drops 5%)&lt;/li&gt;
&lt;li&gt;Set up automated rollback triggers&lt;/li&gt;
&lt;li&gt;Test rollback in staging; verify it's actually fast&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Canary release for agent versions&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Deploy new agent versions to 5% of users first&lt;/li&gt;
&lt;li&gt;Monitor domain-specific metrics, not just error rates&lt;/li&gt;
&lt;li&gt;Rollback immediately if metrics degrade&lt;/li&gt;
&lt;li&gt;Graduate to full rollout only after confidence period&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runbook for agent failure&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;What do you do when the agent breaks?&lt;/li&gt;
&lt;li&gt;Who gets paged? When?&lt;/li&gt;
&lt;li&gt;How long does recovery take?&lt;/li&gt;
&lt;li&gt;Practice this in a staging environment.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion: Determinism as Architecture
&lt;/h2&gt;

&lt;p&gt;The era of unbounded AI agents in production is ending. The era of scoped, boundary-aware, deterministic agents is beginning.&lt;/p&gt;

&lt;p&gt;Microfrontend architectures give you the natural boundaries you need. They give you the architectural safety that mission-critical systems demand. But only if you treat them as such: not just as a way to split your frontend, but as a way to architect AI reliability.&lt;/p&gt;

&lt;p&gt;Your agents are smarter than your code. They're also more unpredictable. Give them constraints. Give them boundaries. Give them MFE isolation.&lt;/p&gt;

&lt;p&gt;Your mission-critical system will thank you when the agent's decision doesn't break the entire platform.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>microfrontends</category>
      <category>architecture</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Module Federation with Vite in production: what changes</title>
      <dc:creator>MFEOrchestrator</dc:creator>
      <pubDate>Thu, 08 Oct 2026 08:10:00 +0000</pubDate>
      <link>https://dev.to/mfeorchestrator/module-federation-with-vite-in-production-what-changes-57k</link>
      <guid>https://dev.to/mfeorchestrator/module-federation-with-vite-in-production-what-changes-57k</guid>
      <description>&lt;p&gt;Module Federation started in Webpack, and for years that is where it stayed. It works on Vite now, through &lt;code&gt;@module-federation/vite&lt;/code&gt;, and works well — but Vite's dev server and Vite's build are two different machines, and Module Federation has to satisfy both. Most production surprises live in that gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does Module Federation actually work with Vite?
&lt;/h2&gt;

&lt;p&gt;Yes. The plugin exposes the same concepts you already know — a host, remotes, exposes, shared dependencies — and a remote built by Vite can be consumed by a host built by Webpack, and the other way round. The container contract is what travels, not the bundler.&lt;/p&gt;

&lt;p&gt;What differs is what happens underneath, and the honest summary is that Vite's dev server does not bundle. It serves native ES modules and transforms on demand. The build does bundle, through Rollup. So the code you exercise all day and the code you ship take different paths through the toolchain.&lt;/p&gt;

&lt;h2&gt;
  
  
  What breaks in production that worked in dev?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dependency deduplication.&lt;/strong&gt; In dev, the browser resolves modules and duplicates are cheap to miss. In the build, sharing is negotiated for real, and a shared library that was silently loaded twice becomes either a singleton conflict or a bundle that ships React more than once.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Module initialisation order.&lt;/strong&gt; The dev server's on-demand transform can hide an import cycle that the bundled output makes fatal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Missing externals.&lt;/strong&gt; A dependency present in dev because something else pulled it in can be absent from a remote's build, and only fails when that remote is loaded — which may be a route most people never open.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these are Vite defects. They are the ordinary difference between resolving modules in a browser and linking them ahead of time — Module Federation simply gives that difference more surface.&lt;/p&gt;

&lt;h2&gt;
  
  
  How should you handle shared dependencies?
&lt;/h2&gt;

&lt;p&gt;Share deliberately and share little. Everything that must be a singleton — the framework runtime, the router, whatever holds global state — should be shared and marked as such. Everything else is usually cheaper duplicated than coordinated.&lt;/p&gt;

&lt;p&gt;The failure worth naming: a shared dependency with a loose version range across several independently released micro frontends means the singleton in production is whichever version happened to load first. That is not a configuration you chose; it is a race you are hosting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where do the remote URLs come from?
&lt;/h2&gt;

&lt;p&gt;In most tutorials, from the bundler config — an object literal mapping each remote to a URL, committed to the host repository. It is the shortest thing that works, and it is also the decision that ends up costing the most.&lt;/p&gt;

&lt;p&gt;Because that literal is the thing that has to change when you release. A new version of one remote means editing the host's config, rebuilding the host, and redeploying the shell — for a change that happened entirely somewhere else. It is the same trap described in &lt;a href="https://mfe-orchestrator.dev/blog/federation-vs-orchestration" rel="noopener noreferrer"&gt;the piece on composition versus deployment&lt;/a&gt;, and Vite does not change it either way.&lt;/p&gt;

&lt;p&gt;The fix is not Vite-specific either: generate that map instead of writing it, from configuration fetched at runtime. The remote &lt;strong&gt;names&lt;/strong&gt; stay in the build, because names are structural. The URLs do not have to.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should you check before shipping?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Build every remote and load them from a built host, not the dev server. This is the single check that catches most of the list above.&lt;/li&gt;
&lt;li&gt;Inspect the output for duplicated framework copies. If React appears twice, sharing is not doing what you think.&lt;/li&gt;
&lt;li&gt;Pin shared dependency versions across micro frontends, or accept that the singleton is decided by load order.&lt;/li&gt;
&lt;li&gt;Open every route that lazily loads a remote. A remote that is never loaded in testing is a remote that was never tested.&lt;/li&gt;
&lt;li&gt;Confirm the remote URLs are resolved at runtime, so a release does not require rebuilding the host.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Module Federation on Vite is production-ready. It is the assumption that the dev server tells you what production will do that is not.&lt;/p&gt;

</description>
      <category>microfrontends</category>
      <category>vite</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Federation Solved Composition. Nobody Solved Deployment Reliability</title>
      <dc:creator>MFEOrchestrator</dc:creator>
      <pubDate>Thu, 08 Oct 2026 08:09:57 +0000</pubDate>
      <link>https://dev.to/mfeorchestrator/federation-solved-composition-nobody-solved-deployment-reliability-1nno</link>
      <guid>https://dev.to/mfeorchestrator/federation-solved-composition-nobody-solved-deployment-reliability-1nno</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Why your microfrontend framework isn't solving your biggest operational problem—and what you're missing&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Conversation I Keep Having
&lt;/h2&gt;

&lt;p&gt;Over the past five years, I've had the same conversation with dozens of engineering teams, over and over:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Them&lt;/strong&gt;: "We're adopting Module Federation. Our team just shipped three new MFEs last quarter. Deployment velocity is great."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me&lt;/strong&gt;: "Nice. How long does a rollback take?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Them&lt;/strong&gt;: &lt;em&gt;pause&lt;/em&gt; "Uhh... if something goes wrong, we have to rebuild the entire frontend, run the pipeline, and redeploy. Maybe 10–15 minutes?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me&lt;/strong&gt;: "And canary releases?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Them&lt;/strong&gt;: &lt;em&gt;longer pause&lt;/em&gt; "We built custom tooling for that. It's... fragile. Each team has their own version."&lt;/p&gt;

&lt;p&gt;The pattern is consistent: &lt;strong&gt;Every team we talk to is strong on composition and weak on operational reliability.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Happened: Federation Won, Then Stopped
&lt;/h2&gt;

&lt;p&gt;Module Federation (Webpack, Vite, others) solved a real problem: &lt;strong&gt;How do you compose independent frontend modules at runtime?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The answer was elegant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build each MFE independently&lt;/li&gt;
&lt;li&gt;Define public contracts (shared dependencies, APIs)&lt;/li&gt;
&lt;li&gt;Load at runtime via manifest&lt;/li&gt;
&lt;li&gt;Compose at the URL/slot level&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Problem solved.&lt;/strong&gt; Netflix, Meta, Shopify, Airbnb—all operating at scale with federation frameworks. Modern, modular, clean architecture.&lt;/p&gt;

&lt;p&gt;But here's what federation &lt;em&gt;didn't&lt;/em&gt; solve:&lt;/p&gt;

&lt;h2&gt;
  
  
  The Unsolved Problem: Safe, Fast Deployment
&lt;/h2&gt;

&lt;p&gt;Federation is about &lt;strong&gt;composition&lt;/strong&gt;. It doesn't say anything about &lt;strong&gt;orchestration&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Think about it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Composition&lt;/strong&gt;: "Which modules load in which slots, and how do they communicate?"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Orchestration&lt;/strong&gt;: "How do we deploy module versions safely, roll them back, and monitor what's happening?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are different problems. Federation frameworks are optimized for the first. The second? You're on your own.&lt;/p&gt;

&lt;h2&gt;
  
  
  What That Looks Like in Practice
&lt;/h2&gt;

&lt;p&gt;Here's a typical MFE deployment workflow today:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Developer commits fix to MFE "Checkout"
2. CI/CD pipeline triggers (full frontend build, not just Checkout)
3. Webpack builds all MFEs: 3–5 minutes
4. Artifacts pushed to CDN/registry
5. Deployment triggers (frontend reconciliation, cache invalidation)
6. Live. Total time: 10–15 minutes.

If something breaks mid-deployment:
   → Rebuild, redeploy. Same 10–15 minutes to rollback.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Meanwhile, in the backend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Developer commits fix to a service
2. CI/CD pipeline triggers (just that service)
3. Build: 1–2 minutes
4. Artifact pushed
5. Kubernetes rolling update: ~30 seconds
6. If bad: rollback to previous version: ~30 seconds
7. Total MTTR: minutes (not from scratch; pre-built versions exist)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend learned decades ago: &lt;strong&gt;Decouple building from deploying.&lt;/strong&gt; But the frontend never got that memo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters (Beyond Speed)
&lt;/h2&gt;

&lt;p&gt;It's not just about milliseconds. Slow deployments create operational debt:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Every team builds custom rollout tooling
&lt;/h3&gt;

&lt;p&gt;Since federation doesn't give you canary releases, each team invents their own:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hand-rolled traffic shifting (5% → 25% → 100%)&lt;/li&gt;
&lt;li&gt;Custom health checks and dashboards&lt;/li&gt;
&lt;li&gt;Manual rollback logic&lt;/li&gt;
&lt;li&gt;Feature flags scattered across codebases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: Fragile, team-specific, expensive to maintain.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. All-or-nothing deployments
&lt;/h3&gt;

&lt;p&gt;A fix in "Checkout" forces you to rebuild and redeploy the entire frontend. Yes, you have module federation, but without a safe deployment layer, you lose the granularity it promises.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Risk profile&lt;/strong&gt;: One small bug in one MFE can take down your whole frontend.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Incident response becomes firefighting
&lt;/h3&gt;

&lt;p&gt;A production incident at 2 AM. Your Checkout MFE is leaking memory. Do you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wait 15 minutes for a full rebuild and redeploy?&lt;/li&gt;
&lt;li&gt;Revert the entire frontend (losing unrelated deploys from the last hour)?&lt;/li&gt;
&lt;li&gt;Blame the framework and move on?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most teams do a combination of all three.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Platform engineering scales poorly
&lt;/h3&gt;

&lt;p&gt;As you add more MFEs, the coordination overhead grows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More teams building custom deployment logic&lt;/li&gt;
&lt;li&gt;More manual orchestration between deployments&lt;/li&gt;
&lt;li&gt;More incidents caused by timing/coordination bugs&lt;/li&gt;
&lt;li&gt;More time spent on toil instead of features&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Federation and Orchestration Are Different
&lt;/h2&gt;

&lt;p&gt;Let me be direct: &lt;strong&gt;This isn't a federation framework problem.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Federation frameworks are doing what they're designed to do—composing modules at runtime. The problem is that the industry conflates &lt;strong&gt;"I have module federation"&lt;/strong&gt; with &lt;strong&gt;"My frontend deployment is reliable."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These are separate concerns:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;Federation Answers&lt;/th&gt;
&lt;th&gt;Orchestration Answers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"How do I load modules at runtime?"&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"How do I deploy a module version safely?"&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"How do I roll out a change gradually?"&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"How do I rollback quickly?"&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"How do I know what's deployed?"&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;You need both.&lt;/strong&gt; Federation for composition. Orchestration for safe deployment.&lt;/p&gt;

&lt;p&gt;Right now, most teams have federation. They're building orchestration ad-hoc, per-team, with custom code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Kubernetes Parallel (and Why It Doesn't Apply)
&lt;/h2&gt;

&lt;p&gt;Some teams say: "Why not just use Kubernetes for the frontend?"&lt;/p&gt;

&lt;p&gt;Valid question. Kubernetes is extraordinary for orchestration—but at the container level. It operates on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pods (not components)&lt;/li&gt;
&lt;li&gt;Replica sets (not versions)&lt;/li&gt;
&lt;li&gt;Rolling updates (not canary with business metrics)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So when you apply Kubernetes thinking to the frontend, you get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Container per MFE? Now every MFE is a "service."&lt;/li&gt;
&lt;li&gt;Rolling updates? You're waiting for container reconciliation—5+ minutes.&lt;/li&gt;
&lt;li&gt;Canary? You need a service mesh (Istio). Now you've added complexity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: Kubernetes works, but you're bending your frontend to fit a container orchestration model, not the other way around.&lt;/p&gt;

&lt;p&gt;The frontend needs orchestration at the &lt;strong&gt;component/bundle level&lt;/strong&gt;, not the container level.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Cost (In Hours)
&lt;/h2&gt;

&lt;p&gt;Let's quantify what you're actually paying for:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Activity&lt;/th&gt;
&lt;th&gt;Hours/Week&lt;/th&gt;
&lt;th&gt;Teams Affected&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Building custom rollout tooling&lt;/td&gt;
&lt;td&gt;3–5&lt;/td&gt;
&lt;td&gt;Platform team&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maintaining per-team deployment scripts&lt;/td&gt;
&lt;td&gt;2–4&lt;/td&gt;
&lt;td&gt;Each team&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Incident response (extra time due to slow rollback)&lt;/td&gt;
&lt;td&gt;1–3&lt;/td&gt;
&lt;td&gt;On-call&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Debugging deployment coordination issues&lt;/td&gt;
&lt;td&gt;2–4&lt;/td&gt;
&lt;td&gt;DevOps/Platform&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total&lt;/td&gt;
&lt;td&gt;8–16&lt;/td&gt;
&lt;td&gt;Org-wide&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For a 20-person org, that's 160–320 hours/year of engineering time spent on tooling that the backend solved in the 1990s.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Should Exist (And Doesn't)
&lt;/h2&gt;

&lt;p&gt;If MFE deployment were solved, here's what you'd have:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Immutable snapshots&lt;/strong&gt; of your MFE versions (not rebuilt every deploy)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safe promotion&lt;/strong&gt;: Deploy to production without a rebuild&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instant rollback&lt;/strong&gt;: Revert to a previous version in ~30 seconds (not rebuild time)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Canary releases&lt;/strong&gt;: Built-in, no custom per-team tooling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability&lt;/strong&gt;: See what's deployed and rollout status in real-time&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This exists for backends (Docker images, Kubernetes, etc.). It doesn't exist for frontends as a standard, integrated layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Diagnostic: Check Your Own Setup
&lt;/h2&gt;

&lt;p&gt;If any of these sound familiar, you're manually orchestrating MFE deployments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have custom scripts for canary releases&lt;/li&gt;
&lt;li&gt;Rollback requires re-running your CI/CD pipeline&lt;/li&gt;
&lt;li&gt;You don't have a shared "deployment status" view&lt;/li&gt;
&lt;li&gt;Different MFE teams use different rollout processes&lt;/li&gt;
&lt;li&gt;Your MTTR (mean time to recovery) is in minutes, not seconds&lt;/li&gt;
&lt;li&gt;You've had "cascading failures" where one MFE's deployment issue affected others&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you check even 2–3 of these, you're incurring operational debt that federation won't fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Gap
&lt;/h2&gt;

&lt;p&gt;Federation solved: &lt;strong&gt;"How do I structure my code?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The unsolved gap: &lt;strong&gt;"How do I deploy my code safely?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The irony: The backend solved this 30 years ago. But every MFE team rebuilds the solution from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;We're working on something to close this gap. The idea: a &lt;strong&gt;control plane for microfrontends&lt;/strong&gt; that treats deployment and orchestration as a first-class concern—not an afterthought, not a per-team rebuild.&lt;/p&gt;

&lt;p&gt;In the meantime, ask yourself: If your backend team managed deployments the way your frontend does, would you accept it?&lt;/p&gt;

&lt;p&gt;If the answer is no, you've identified the problem.&lt;/p&gt;

&lt;p&gt;Follow along. We'll share what we're building.&lt;/p&gt;

&lt;h2&gt;
  
  
  Share Your Experience
&lt;/h2&gt;

&lt;p&gt;If you're managing MFE deployments: What's your biggest pain point? How long does a rollback actually take? How much custom tooling are you maintaining?&lt;/p&gt;

&lt;p&gt;The more I hear, the clearer the picture becomes.&lt;/p&gt;

</description>
      <category>microfrontends</category>
      <category>devops</category>
      <category>webpack</category>
      <category>architecture</category>
    </item>
    <item>
      <title>How to roll back a micro frontend in 30 seconds (without rebuilding the host)</title>
      <dc:creator>MFEOrchestrator</dc:creator>
      <pubDate>Thu, 08 Oct 2026 08:09:52 +0000</pubDate>
      <link>https://dev.to/mfeorchestrator/how-to-roll-back-a-micro-frontend-in-30-seconds-without-rebuilding-the-host-1bp1</link>
      <guid>https://dev.to/mfeorchestrator/how-to-roll-back-a-micro-frontend-in-30-seconds-without-rebuilding-the-host-1bp1</guid>
      <description>&lt;p&gt;The release went out twenty minutes ago. Checkout throws on Safari, the error rate is climbing, and someone has already asked the question everybody dreads: how fast can we undo this?&lt;/p&gt;

&lt;p&gt;If your micro frontends load through Module Federation and the version each environment serves lives in the host's source, the honest answer is ten to fifteen minutes — on a good day, with CI free and nobody else's pipeline ahead of yours. This is about why that number is what it is, and how to make it thirty seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is rolling back a micro frontend so slow?
&lt;/h2&gt;

&lt;p&gt;Because in most setups the rollback is not a rollback. It is a redeploy. The host holds a list of remotes — a file, usually committed — mapping each micro frontend to a URL. Change which version you serve and you have changed the host's source. Changing the host's source means building the host again.&lt;/p&gt;

&lt;p&gt;So the fix for a broken checkout widget is a full rebuild and redeploy of the shell containing it. &lt;strong&gt;The blast radius of the recovery is larger than the blast radius of the bug.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the fifteen minutes actually go
&lt;/h2&gt;

&lt;p&gt;Worth breaking down, because the instinct is to blame the build, and the build is rarely the biggest share.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Someone decides what to revert. Not mechanical: the last deploy may have carried three micro frontends, and only one is broken.&lt;/li&gt;
&lt;li&gt;Revert the commit, open a PR. If the branch is protected — and on a host application it should be — that needs a review.&lt;/li&gt;
&lt;li&gt;Wait for a CI runner. On a shared plan at three in the afternoon, this is dead time you do not control.&lt;/li&gt;
&lt;li&gt;Install, build, test. The host's build is the whole shell: every dependency, every micro frontend reference.&lt;/li&gt;
&lt;li&gt;Deploy, invalidate the CDN, wait for the edge to actually drop the old bundle.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Only step four is engineering. The rest is queueing and process, which is why a faster build machine barely moves the number.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does Module Federation actually give you?
&lt;/h2&gt;

&lt;p&gt;Runtime loading, and that is genuinely a lot: the host fetches a remote's bundle when it needs it, and shared dependencies get negotiated rather than duplicated.&lt;/p&gt;

&lt;p&gt;What it does not give you is a decision. Module Federation loads whatever URL you point it at. It holds no opinion about which version staging should serve versus production, keeps no record of what was live yesterday, and offers no way to change the answer without changing the code that contains it. Composition is solved. Version resolution is left as an exercise.&lt;/p&gt;

&lt;h2&gt;
  
  
  What makes a thirty-second rollback possible?
&lt;/h2&gt;

&lt;p&gt;One change: the version an environment serves stops being a build-time constant and becomes runtime data.&lt;/p&gt;

&lt;p&gt;Concretely, the host stops importing a remotes map and starts fetching one. On startup it asks a single question — which versions should I load right now? — and gets back a small JSON document. The bundles do not move; they were uploaded already, immutable already, sitting behind a CDN already. The only thing a rollback changes is which of them the answer points to.&lt;/p&gt;

&lt;p&gt;That is why it is fast. Nothing is rebuilt because nothing needs building: the version you are rolling back to was built weeks ago and never deleted.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you roll back in thirty seconds?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Find the environment serving the broken version.&lt;/li&gt;
&lt;li&gt;Pick the previous version from its history. It is still there — immutable artifacts are not garbage collected on deploy.&lt;/li&gt;
&lt;li&gt;Point the environment at it, and confirm.&lt;/li&gt;
&lt;li&gt;The next page load fetches the new configuration and mounts the old bundle.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No PR, no CI, no host deploy. The rollback touches one record, and that record is the only thing that was ever environment-specific.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does this work with both Webpack and Vite?
&lt;/h2&gt;

&lt;p&gt;Yes, and it is the same shape in both. Module Federation is a first-party plugin in Webpack and Rspack, and reaches Vite through &lt;code&gt;@module-federation/vite&lt;/code&gt;. What differs is where the remotes map is declared, not that it is declared.&lt;/p&gt;

&lt;p&gt;The change is identical either way: instead of writing the remotes object literally into the bundler config, you generate it from configuration fetched at runtime. The bundler still needs the remote &lt;strong&gt;names&lt;/strong&gt; at build time — that part is genuinely static — but the URLs behind those names do not have to be.&lt;/p&gt;

&lt;h2&gt;
  
  
  What can still go wrong?
&lt;/h2&gt;

&lt;p&gt;Plenty. A piece that says otherwise is selling you something.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Shared dependency drift.&lt;/strong&gt; If the broken version bumped a shared library and the host negotiated around it, rolling back one remote can leave the singleton at a version the older code never saw.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;In-flight sessions.&lt;/strong&gt; Users mid-session keep the bundle their browser already holds until they reload. The rollback is instant for new page loads and eventual for everyone else.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration caching.&lt;/strong&gt; If the runtime config sits at the edge with a long TTL, your fast path is only as fast as that TTL. Keep it short, or make invalidation part of the rollback.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contract changes.&lt;/strong&gt; If the broken release also changed an API contract, the backend has moved on. Rolling the frontend back does not roll the contract back.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this makes the approach worse than rebuilding the host. The rebuild has every one of these problems too — plus the fifteen minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  And if you would rather not need the rollback?
&lt;/h2&gt;

&lt;p&gt;A rollback is the blunt instrument: something is broken for everyone, and you are undoing it. The considered version of the same mechanism is a canary release. Once the version an environment serves is runtime data, it can also be a different answer for different users — which is how you find out a release is bad while it is still reaching two percent of traffic. We wrote about &lt;a&gt;how that works, and what it costs&lt;/a&gt; separately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do you need a control plane for this?
&lt;/h2&gt;

&lt;p&gt;No. The mechanism is not complicated, and you can build it: a JSON document in object storage, a fetch on host startup, something to write the file.&lt;/p&gt;

&lt;p&gt;What you end up maintaining is everything around it. Somewhere to see which version each environment serves without opening a bucket. A history, so “the previous version” is a fact rather than a memory. Permissions, because whoever can write that file can change production. An audit trail, for when someone asks who rolled back and when. Validation, so a typo in a version string fails loudly instead of serving a blank page. A path for CI to publish a build and register it in one step.&lt;/p&gt;

&lt;p&gt;That is the part that takes the time, and it is the part every team rebuilds. &lt;a href="https://mfe-orchestrator.dev" rel="noopener noreferrer"&gt;MFE Orchestrator&lt;/a&gt; is our answer to it — open source, self-hostable — but the idea outlives the tool: &lt;strong&gt;as long as the version lives in the host's build, your rollback time is your host's deploy time.&lt;/strong&gt; Move the decision out of the build and the number collapses to whatever it takes to write one record.&lt;/p&gt;

&lt;p&gt;Thirty seconds is not a marketing figure. It is what remains once you stop rebuilding an entire application in order to change your mind about which version of one widget to serve.&lt;/p&gt;

</description>
      <category>microfrontends</category>
      <category>devops</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
  </channel>
</rss>
