<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=490755098261949&amp;ev=PageView&amp;noscript=1">

:tada:2024 WEBBY WINNER: The Crate & Barrel mobile app won a Webby Award!

Micro Frontend Architecture: What, Why, When and How

Santheep Kumar
Author Santheep Kumar
Published On Jul 24, 2023
featured_microfrontend

In the ever-evolving landscape of web development, constant change is the norm. Enter micro frontends: a groundbreaking architectural pattern promising a fresh take on flexibility, scalability, and collaboration. Micro frontends break down monolithic frontend applications into smaller, more manageable modules, empowering developers to work in their own space while weaving together a seamless user experience.

Here’s what to expect from this blog post:

  • An introduction to the concept of micro frontends and how they differ from traditional monolithic applications
  • An explanation of the key benefits offered by micro frontends
  • A hands-on demonstration of how to implement micro frontends using React, with real code snippets to illustrate the concepts
  • An exploration of the challenges and considerations when adopting micro frontends
  • A vision of the future of frontend development

What Is a Micro Frontend?

 

WhatisMicroFrontend@2x

Micro frontends draw inspiration from the principles of microservices found in backend development, pushing for the breakdown of frontend applications into bite-sized, manageable units. In this structure, each module or 'micro frontend' embodies a distinct feature or functionality of the application. These micro frontends can be developed, rolled out, and maintained independently, harnessing diverse technologies and frameworks.


Unlike traditional monolithic applications, micro frontends are designed to communicate and interact with each other, creating a seamless user experience. This communication is typically established through well-defined APIs, events, or shared state management. By separating frontend modules, micro frontends empower teams to operate autonomously, allowing for quicker iteration, more efficient development cycles, and easier maintenance.

The Benefits of Micro Frontends

 

1. Independent Development & Deployment

Micro frontends liberate development teams from the constraints of a monolithic codebase. Each micro frontend represents a separate codebase that can be developed and deployed independently. This independence allows teams to work at their own pace, using the technologies, frameworks, and programming languages of their choice. Different teams can focus on specific micro frontends without being blocked by others, resulting in accelerated development and increased productivity.

2. Scalability & Performance Optimization

With micro frontends, horizontal scalability becomes achievable. Each micro frontend can be deployed and scaled independently based on its specific requirements. This modular architecture enables teams to optimize the performance of individual modules without affecting the entire application. Additionally, micro frontends can be loaded asynchronously, leading to faster initial load times and enhanced user experience.

3. Flexibility & Technology Diversity

Micro frontends provide the flexibility to choose the most suitable technology stack for each module. Different micro frontends can utilize different frameworks, libraries, or programming languages based on their unique needs. This flexibility fosters innovation, allows teams to experiment with new technologies, and enables them to leverage the strengths of each tool without compromising the overall application architecture.

4. Easy Maintenance & Upgrades

Maintaining and upgrading a large frontend application can be a daunting task. Micro frontends offer a solution to this challenge by breaking down the application into smaller, more manageable units. Since each micro frontend is self-contained, maintenance and upgrades can be performed independently, reducing the risk of introducing regressions and facilitating smoother releases and rollbacks.

5. Team Collaboration and Autonomy

Micro frontends promote collaboration among multiple teams, each responsible for developing and maintaining specific modules. Teams can work independently, making decisions regarding technology choices, development processes, and deployment strategies without interfering with others. This autonomy boosts team morale, encourages ownership, and fosters a culture of innovation and continuous improvement.

Implementing Micro Frontends With React

React, a popular JavaScript library for building user interfaces, is ideal for implementing micro frontends due to its component-based architecture. Here's an example that demonstrates how React can be used in a micro frontend setup:

 

Micro Frontend A: React App with Header Component

import React from 'react';

const Header: React.FC = (): JSX.Element => {
  return <div className="p-10 bg-gray-400 m-10 rounded-md">My Header</div>;
};

export default Header;

 

Micro Frontend A: Webpack Config

const HtmlWebPackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');

const deps = require('./package.json').dependencies;
module.exports = (_, argv) => ({
  output: {
    publicPath: 'http://localhost:3001/'
  },

  resolve: {
    extensions: ['.tsx', '.ts', '.jsx', '.js', '.json']
  },

  devServer: {
    port: 3001,
    historyApiFallback: true
  },

  module: {
    rules: [
      {
        test: /\.m?js/,
        type: 'javascript/auto',
        resolve: {
          fullySpecified: false
        }
      },
      {
        test: /\.(css|s[ac]ss)$/i,
        use: ['style-loader', 'css-loader', 'postcss-loader']
      },
      {
        test: /\.(ts|tsx|js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      }
    ]
  },

  plugins: [
    new ModuleFederationPlugin({
      name: 'header',
      filename: 'remoteEntry.js',
      remotes: {},
      exposes: {
        './Header': './src/Header.tsx'
      },
      shared: {
        ...deps,
        react: {
          singleton: true,
          requiredVersion: deps.react
        },
        'react-dom': {
          singleton: true,
          requiredVersion: deps['react-dom']
        }
      }
    }),
    new HtmlWebPackPlugin({
      template: './src/index.html'
    })
  ]
});

 

Micro Frontend B: React App with Footer Component

import React from 'react';

const Footer: React.FC = (): JSX.Element => {
  return <div className="p-10 bg-gray-400 m-10 rounded-md">My Footer</div>;
};

export default Footer;

 

Micro Frontend B: Webpack Config

const HtmlWebPackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');

const deps = require('./package.json').dependencies;
module.exports = (_, argv) => ({
  output: {
    publicPath: 'http://localhost:3002/'
  },

  resolve: {
    extensions: ['.tsx', '.ts', '.jsx', '.js', '.json']
  },

  devServer: {
    port: 3002,
    historyApiFallback: true
  },

  module: {
    rules: [
      {
        test: /\.m?js/,
        type: 'javascript/auto',
        resolve: {
          fullySpecified: false
        }
      },
      {
        test: /\.(css|s[ac]ss)$/i,
        use: ['style-loader', 'css-loader', 'postcss-loader']
      },
      {
        test: /\.(ts|tsx|js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      }
    ]
  },

  plugins: [
    new ModuleFederationPlugin({
      name: 'footer',
      filename: 'remoteEntry.js',
      remotes: {},
      exposes: {
        './Footer': './src/Footer.tsx'
      },
      shared: {
        ...deps,
        react: {
          singleton: true,
          requiredVersion: deps.react
        },
        'react-dom': {
          singleton: true,
          requiredVersion: deps['react-dom']
        }
      }
    }),
    new HtmlWebPackPlugin({
      template: './src/index.html'
    })
  ]
});

 

Main Application: Host Application Rendering Both Header & Footer Micro Frontends

import React from 'react';
import ReactDOM from 'react-dom';

import './index.scss';
// Micro Frontend A
import Header from 'header/Header';
// Micro Frontend B
import Footer from 'footer/Footer';

const App = () => (
  <div className="mt-10 text-3xl mx-auto max-w-6xl">
    <Header />
    <div>My App</div>
    <Footer />
  </div>
);
ReactDOM.render(<App />, document.getElementById('app'));

 

Main Application: Webpack Config

const HtmlWebPackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');

const deps = require('./package.json').dependencies;
module.exports = (_, argv) => ({
  output: {
    publicPath: 'http://localhost:3003/'
  },

  resolve: {
    extensions: ['.tsx', '.ts', '.jsx', '.js', '.json']
  },

  devServer: {
    port: 3003,
    historyApiFallback: true
  },

  module: {
    rules: [
      {
        test: /\.m?js/,
        type: 'javascript/auto',
        resolve: {
          fullySpecified: false
        }
      },
      {
        test: /\.(css|s[ac]ss)$/i,
        use: ['style-loader', 'css-loader', 'postcss-loader']
      },
      {
        test: /\.(ts|tsx|js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      }
    ]
  },

  plugins: [
    new ModuleFederationPlugin({
      name: 'home',
      filename: 'remoteEntry.js',
      remotes: {
        // Micro Frontend A
        header: 'header@http://localhost:3001/remoteEntry.js',
        // Micro Frontend B
        footer: 'header@http://localhost:3002/remoteEntry.js'
      },
      exposes: {}
    }),
    new HtmlWebPackPlugin({
      template: './src/index.html'
    })
  ]
});
In this example, we have a main application component (MainApplication) that integrates two micro frontends (MicroFrontendA and MicroFrontendB) built with React. Each micro frontend is developed as a separate React component, encapsulating its specific functionality and user interface.

The main application component acts as a composition root, rendering the micro frontends alongside other components. By breaking down the application into smaller, reusable components, React enables teams to develop and maintain each micro frontend independently.

In the ever-evolving landscape of web development, constant change is the norm. Enter micro frontends: a groundbreaking architectural pattern promising a fresh take on flexibility, scalability, and collaboration. Micro frontends break down monolithic frontend applications into smaller, more manageable modules, empowering developers to work in their own space while weaving together a seamless user experience.

Here’s what to expect from this blog post:

  • An introduction to the concept of micro frontends and how they differ from traditional monolithic applications
  • An explanation of the key benefits offered by micro frontends
  • A hands-on demonstration of how to implement micro frontends using React, with real code snippets to illustrate the concepts
  • An exploration of the challenges and considerations when adopting micro frontends
  • A vision of the future of frontend development

Micro frontends are a game-changer in the world of frontend development. They give teams the freedom to step away from the restrictive confines of monolithic applications and explore the adaptability of modular architectures. By breaking down applications into more digestible, standalone parts, micro frontends open up new opportunities for separate development, efficient scaling, and increased flexibility. And with React in their toolkit, developers have the power to easily implement and integrate micro frontends thanks to its component-based architecture.

Of course, shifting to micro frontends doesn't come without its considerations. It's crucial to think carefully about communication strategies, routing mechanisms, shared dependencies, and testing methods before implementing this new approach. With all that in mind, there’s nothing left to do but start exploring — and we hope this blog serves as a helpful primer as you begin diving into the world of micro frontends.

In the ever-evolving landscape of web development, constant change is the norm. Enter micro frontends: a groundbreaking architectural pattern promising a fresh take on flexibility, scalability, and collaboration. Micro frontends break down monolithic frontend applications into smaller, more manageable modules, empowering developers to work in their own space while weaving together a seamless user experience.

Here’s what to expect from this blog post:

  • An introduction to the concept of micro frontends and how they differ from traditional monolithic applications
  • An explanation of the key benefits offered by micro frontends
  • A hands-on demonstration of how to implement micro frontends using React, with real code snippets to illustrate the concepts
  • An exploration of the challenges and considerations when adopting micro frontends
  • A vision of the future of frontend development
LET'S TALK IT OUT.

Figuring out your next step? We're here for you.

Or drop us a line.

hello@heady.io