What is NOT a Micro-Frontend: Clearing the Confusion
Felice Lombardi

Felice Lombardi @managerfx

About: Software Engineer

Location:
Milan, Italy
Joined:
Nov 17, 2023

What is NOT a Micro-Frontend: Clearing the Confusion

Publish Date: Jun 13
2 4

As a Senior Frontend Architect, I've witnessed countless discussions about micro-frontends where teams mistakenly identify architectural patterns, leading to poor decisions and technical debt.

My Pain Point: The Tragedy of Misunderstood Architecture

Let me tell you a story that still haunts me. I was in a crucial architectural meeting where we were deciding the future of our frontend strategy. The lead architect confidently presented their "micro-frontend solution" – and I watched in horror as they described what was essentially a glorified component library.

"We'll create reusable components," they enthusiastically explained, "the Login component, the Dashboard component, the UserProfile component. Each team can own their components, and we'll have micro-frontends!"

Fortunately, I managed to catch the problem in time. After hours of discussion and presenting concrete examples, I was able to convince them of the true meaning of what a micro-frontend entails. We'll explore what that means later.

But that wasn't the worst of it. In another project, I witnessed pure madness: an architect seriously proposing to compose entire pages using multiple iframes. "We'll have the header iframe, the sidebar iframe, the main content iframe, and the footer iframe," they said with a straight face. "Each team can own its iframe!"

Thankfully, a few days later, they walked back their proposal entirely.


This article aims to prevent that pain by clearly defining what micro-frontends are NOT, so you can avoid these painful mistakes.

Let's clarify what micro-frontends truly are by examining what they are NOT.


What Micro-Frontends Are NOT

❌ NOT Just Multiple SPAs Behind a Reverse Proxy

Many developers think that having several Single Page Applications (SPAs) running on different ports and routing them through a reverse proxy creates a micro-frontend architecture. This is one of the most common misconceptions.

# This is NOT a micro-frontend architecture
server {
    location /dashboard { proxy_pass http://react-dashboard:3000; }
    location /profile { proxy_pass http://vue-profile:3001; }
    location /billing { proxy_pass http://angular-billing:3002; }
}
Enter fullscreen mode Exit fullscreen mode

Why it fails:

  • Full page reloads: When users navigate from /dashboard to /profile, the entire page reloads, breaking the single-page application experience.
  • No shared state: User authentication, cart data, or any global state is lost between applications.
  • Inconsistent UI: Each app loads its own CSS, fonts, and UI components, leading to visual flickering and inconsistent design.
  • Performance issues: Each transition requires downloading new JavaScript bundles, CSS files, and fresh API calls.
  • Browser history problems: Back button behavior becomes unpredictable across different applications.

Real-world analogy: It's like having separate websites pretending to be a single application – imagine if Gmail reloaded the entire page every time you switched from Inbox to Compose!


❌ NOT a Component Library or Design System

Another common confusion happens when developers think that using shared UI components from a design system equates to micro-frontends. While component libraries are valuable, they are fundamentally different from micro-frontend architecture.

// This is a component library, NOT a micro-frontend
import { Button, Modal, DataTable } from '@company/ui-components';

function UserManagement() {
    return (
        <div>
            <Button onClick={handleCreate}>Create User</Button>
            <DataTable data={users} />
        </div>
    );
}
Enter fullscreen mode Exit fullscreen mode

Why it fails:

  • Shared dependencies: All teams must use the same version of the component library, creating coordination overhead.
  • No independent deployments: If the component library changes, all applications must update and redeploy.
  • Single point of failure: A bug in the shared component affects every application that uses it.
  • Limited team autonomy: Teams cannot make independent technology choices or significantly customize components.
  • Not business-focused: Components are UI building blocks, not complete business functionalities.

Think of it this way: Component libraries are like LEGO bricks that everyone shares, but micro-frontends are like complete LEGO sets (spaceship, castle, car) that different teams build and can swap in and out of a larger city.


❌ NOT iframe-Based Solutions

While iframes technically allow embedding different applications, they create more problems than they solve and represent an outdated approach that many beginners mistakenly consider "micro-frontends."

<div class="app-container">
    <iframe src="/dashboard-app" width="100%" height="500px"></iframe>
    <iframe src="/analytics-app" width="100%" height="400px"></iframe>
</div>
Enter fullscreen mode Exit fullscreen mode

Why it fails:

  • Styling nightmare: Each iframe has its own CSS context, making it impossible to create consistent spacing, fonts, and colors across applications.
  • Communication barriers: Parent and child applications struggle to share data or coordinate actions (like showing loading states).
  • Accessibility issues: Screen readers and keyboard navigation break across iframe boundaries, failing users with disabilities.
  • Performance bottlenecks: Each iframe loads a complete HTML document with its own CSS and JavaScript, consuming unnecessary resources.
  • Poor mobile responsiveness: Iframes do not play well on mobile devices, leading to scrolling issues and touch interaction problems.
  • SEO challenges: Search engines have difficulty correctly indexing content within iframes.

Real-world comparison: Using iframes is like having separate TV screens for each room in your house instead of having one smart TV that can display different content – technically possible but clunky and inefficient.


❌ NOT Monorepos with Multiple Apps

Many developers assume that organizing multiple applications within a single repository (monorepo) automatically creates a micro-frontend architecture. This is a fundamental misunderstanding of what micro-frontends represent.

{
  "name": "company-apps",
  "workspaces": [
    "apps/dashboard",
    "apps/admin",
    "apps/mobile"
  ]
}
Enter fullscreen mode Exit fullscreen mode

Why it fails:

  • Deployment coupling: Even if apps are separate, they are often deployed together, defeating the purpose of independent releases.
  • Shared build process: All applications typically use the same build tools, Node.js version, and deployment pipeline, limiting technology choices.
  • Code organization ≠ Runtime integration: Having separate folders doesn't mean the applications work together as a unified experience.
  • Missing runtime composition: Users still navigate between entirely separate applications rather than seamlessly integrated functionalities.
  • Coordination overhead: Teams still need to coordinate changes, updates, and releases because everything lives in the same repository.

Simple analogy: A monorepo with multiple apps is like having separate apartments in the same building – they are organized together but are still completely independent living spaces. Micro-frontends are more like having different rooms in the same house that work together to create a single living experience.


❌ NOT Route-Based Code Splitting

This is probably the most subtle misconception. Many developers believe that splitting their application's code based on routes and dynamically loading them creates micro-frontends. While code splitting is an excellent optimization technique, it's not the same as micro-frontend architecture.

// This is code splitting, NOT micro-frontend
const Dashboard = lazy(() => import('./Dashboard'));
const Profile = lazy(() => import('./Profile'));

function App() {
    return (
        <Router>
            <Routes>
                <Route path="/dashboard" element={<Dashboard />} />
                <Route path="/profile" element={<Profile />} />
            </Routes>
        </Router>
    );
}
Enter fullscreen mode Exit fullscreen mode

Why it fails:

  • Single deployment unit: All code splitting happens within one application that is deployed as a single unit.
  • Single team ownership: One team still owns the entire application, including all routes and functionalities.
  • Shared dependencies: All route components use the same React version, same build tools, same everything.
  • Build-time splitting: The splitting happens when you build the app, not when different teams deploy their functionalities.
  • Technology lock-in: You can't have Dashboard in React and Profile in Vue – everything must use the same technology stack.
  • Coordination required: Adding new routes or changing shared logic still requires coordination with the entire team.

Easy way to remember: Code splitting is like having a large closet with organized sections (shirts, pants, shoes) – it's still one closet owned by one person. Micro-frontends are like having separate wardrobes that different people own and manage, but they all contribute to a unified clothing experience.


What Micro-Frontends Really Are

Micro-frontends are independently deployable frontend applications that:

  • Work together in a single page/browser context.
  • Are owned by different teams with full autonomy.
  • Are deployed independently without coordination.
  • Are integrated at runtime using composition techniques.

✅ A True Micro-Frontend Example

// Shell application (container)
import { registerApplication, start } from 'single-spa';

registerApplication({
    name: 'dashboard',
    app: () => System.import('@company/dashboard'),
    activeWhen: ['/dashboard']
});

registerApplication({
    name: 'user-profile',
    app: () => System.import('@company/user-profile'),
    activeWhen: ['/profile']
});

start();
Enter fullscreen mode Exit fullscreen mode
// Individual micro-frontend (dashboard team)
import React from 'react';
import ReactDOM from 'react-dom';
import singleSpaReact from 'single-spa-react';

const Dashboard = () => <div>Dashboard Content</div>;

const lifecycles = singleSpaReact({
    React,
    ReactDOM,
    rootComponent: Dashboard
});

export const { bootstrap, mount, unmount } = lifecycles;
Enter fullscreen mode Exit fullscreen mode

Key Indicators You're Doing Micro-Frontends Correctly

✅ Different teams can deploy independently.
✅ Applications seamlessly integrate at runtime.
✅ Teams can choose different technologies.
✅ Shared navigation and consistent UX.
✅ Applications can communicate when necessary.


When NOT to Use Micro-Frontends

  • Small teams (< 3 frontend teams)
  • Simple applications
  • Tight coupling requirements
  • Performance is hyper-critical
  • Limited infrastructure resources

Conclusion

Micro-frontends solve organizational problems, not technical ones. They enable team autonomy and independent deployment at the cost of increased complexity. Before adopting them, ensure you have the team structure and organizational needs that justify the architectural overhead.

The key is to understand that micro-frontends are about runtime integration of independently deployed applications, not just splitting code or using multiple technologies.


The Definitive Definition

To close this discussion, I'll share the definition from Luca Mezzalira, one of the most respected voices in the micro-frontend community and author of "Building Micro-Frontends":

"Micro-frontends are the technical representation of a business subdomain. They allow independent implementation with the same or different technology. Finally, they should minimise the code shared and owned by other subdomains owned by a single team."

This definition perfectly captures the essence:

  • Focus on business subdomain: Not technical functionalities, but complete business capabilities.
  • Strong boundaries: Clear separation of concerns and responsibilities.
  • Clear contracts: Well-defined interfaces for communication.
  • No shared logic: True independence between different subdomains.

When evaluating whether you're building true micro-frontends, ask yourself: "Does this represent a complete business subdomain with its own team, deployment cycle, and clear boundaries?" If the answer is no, you're likely dealing with one of the anti-patterns we've discussed.


What's your experience with micro-frontends? Have you seen these anti-patterns in your organization? Share your thoughts in the comments below! 👇

Comments 4 total

  • david duymelinck
    david duymelinckJun 14, 2025

    Iframes that is blast form the past :)

    I'm still skeptical about micro frontends. In the backend a micro-service can be a solution if you need to hyperscale. But modular architecture is for me a great way to prepare the scaling, and for most sites that is good enough.
    What is the point for you to go from modular to micro frontends?

    Micro-services can have multiple languages, but I prefer to not have a language per mico-service. A micro-service should require the strengths of a language.
    With micro frontends i don't see the reason to introduce multiple view library runtimes because of teams.
    In my backend mindset I want to send as little data to the browser as possible. This lets do servers more requests, and it is a performance win in the browser.

    • Felice Lombardi
      Felice LombardiJun 14, 2025

      Totally fair take, and I think a lot of the skepticism is well-founded.

      Personally, the shift from modular to micro frontends only makes sense in very specific scenarios. Usually it’s when you have multiple teams working on clearly separated domains, with independent release cycles, and sometimes even different business units involved. Even in those cases, the trade-offs are significant.

      For most applications, a well-structured modular architecture does the job just fine. It’s easier to maintain, test, and optimize especially if, like you said, you’re focused on sending minimal data to the browser to keep performance tight.

      And yeah, introducing multiple frontend frameworks just to accommodate team preferences doesn’t feel like a good justification. A consistent runtime and UI layer goes a long way in keeping things efficient and maintainable.

  • Nevo David
    Nevo DavidJun 14, 2025

    honestly this hit home for me - i’ve watched people keep falling for the same traps too tbh. you think it’s just lack of clarity or is it folks just rushing for hype architectures without looking at what actually fits their needs?

    • Felice Lombardi
      Felice LombardiJun 14, 2025

      Look, from what I’ve seen, a lot of architects (especially in consulting firms) tend to push for whatever tech is trending just because it’s cool… without really understanding when to use it, or even what it actually is in the first place!

Add comment