
Micro Frontends: Breaking Down the Monolith (Without Breaking Your Brain)
🧠 What Are Micro Frontends?
Micro frontends are the frontend equivalent of microservices.
Instead of building one massive app with a single deployment pipeline, you break your UI into smaller, independently developed and deployed apps. Each one owns a feature or domain and can be built by different teams—even with different tech stacks, if needed.
🤔 Why Would Anyone Do This?
Because monolithic frontends suck when your team (or company) grows.
Benefits:
- Team Autonomy – Each team owns their codebase, build, and deploy pipeline.
- Independent Deployments – No more waiting for a global release just to fix a bug in one page.
- Code Isolation – No global styles bleeding everywhere or shared state collisions.
- Scalability – Good luck scaling a 500k line React app. Now imagine five 100k line apps instead.
⚙️ How Do Micro Frontends Actually Work?
There are a few common techniques:
1. iframes
Old-school but reliable. Great isolation. Terrible integration.
2. Module Federation (Webpack 5)
The hot newness. Lets you load React components from a remote build at runtime.
3. Runtime Composition
You use something like import()
or <script>
tags and render components dynamically.
4. Single-spa or custom routers
Combine different apps via a global router or layout system.
🧱 Architecture Overview
+----------------------------+
| Shell / Host App |
| (Header, Nav, Routing) |
+-----------+----------------
|
v
+----------------------------+
| Microfrontend: Search |
| Loads remotely via MF |
+----------------------------+
+----------------------------+
| Microfrontend: Cart |
| Loads remotely via MF |
+----------------------------+
Each child app is deployed independently and consumed by the shell app.
🧪 Simple React Example (Module Federation)
Let's say we have two projects:
app-shell
: The main container app.remote-header
: A standalone React app that exports aHeader
component.
remote-header (webpack.config.js)
new ModuleFederationPlugin({
name: "remote_header",
filename: "remoteEntry.js",
exposes: {
"./Header": "./src/Header",
},
shared: { react: { singleton: true }, "react-dom": { singleton: true } },
});
app-shell (webpack.config.js)
new ModuleFederationPlugin({
name: "app_shell",
remotes: {
remote_header: "remote_header@http://localhost:3001/remoteEntry.js",
},
shared: { react: { singleton: true }, "react-dom": { singleton: true } },
});
Shell App Usage
import React, { Suspense } from "react";
const Header = React.lazy(() => import("remote_header/Header"));
export default function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<Header />
<main>Your main app goes here</main>
</Suspense>
);
}
🚫 When Micro Frontends Are Overkill
- You have a small app or a single dev team.
- You don't want to deal with deployment orchestration.
- You like sleeping.
✅ When Micro Frontends Are Awesome
- You have 3+ dev teams and tons of surface area.
- You want release independence.
- Your app is already groaning under its own size.
🧯 Final Thoughts
Micro frontends can feel like overkill—until they’re not. When done right, they let you scale your frontend teams and tech stacks with real independence.
And if you want to start experimenting? 👉 Try breaking off just one piece of your app as a microfrontend. See how it feels. You don’t have to go all-in on day one.
Need help building one? Hit me up. I’ve made all the mistakes so you don’t have to.