Going Modular: The Benefits and Challenges of Micro frontends

Going Modular: The Benefits and Challenges of Micro frontends

Introduction

Micro frontends have emerged as a powerful approach to frontend development, offering a way to decompose monolithic applications into smaller, more agile components. Much like microservices have revolutionized backend development, micro frontends are changing the way developers approach frontend architecture. In this blog post, we will explore the concept of micro frontends and delve into their benefits, use cases, and best practices. By the end of this post, you'll have a solid understanding of how micro frontends can help you build more scalable and modular frontend applications, while also improving developer productivity and user experience.

What is Microfrontends?

Micro frontends are small, independently deployable frontend applications that are combined to create a larger application. Each micro frontend typically focuses on a single business capability and is developed and deployed separately from the other micro frontends.

Benefits of Microfrontends

There are several benefits to working with micro frontends. One of the most significant benefits is the ability to break down a large, monolithic front-end application into smaller, more manageable pieces. This can make it easier to maintain and develop the application over time. It can also make it easier to scale the application, as each micro frontend can be scaled independently of the others.

Another benefit of micro frontends is the ability to use different front-end technologies and frameworks for different parts of the application. This can allow teams to use the technology that best suits their needs, rather than being constrained by a single technology stack.

Best Practices for Developing Microfrontends

When developing micro frontends, there are several best practices to keep in mind. One of the most important is to design micro frontends to be as independent as possible. This means that each micro frontend should be responsible for its state management and should not rely on other micro frontends for data.

Another best practice is to use a common set of design patterns and guidelines across all micro frontends. This can help ensure consistency across the application and make it easier for developers to understand and work with each micro frontend.

Finally, it's important to have a strong testing strategy in place for micro frontends. Because micro frontends are developed and deployed independently of each other, it's important to have automated tests in place to ensure that changes to one micro frontend do not break other micro frontends.

Micro frontends can be implemented using a variety of technologies and frameworks. In this section, we will explore some of the popular micro frontend technologies available in the market today.

Technologies to take in mind when using micro frontends

Single-spa

Single-spa is a popular open-source micro frontend framework that allows developers to build and deploy micro frontends using a variety of frontend frameworks, including React, Angular, and Vue. Single-spa provides a set of APIs and tools for managing the lifecycle of micro frontends and routing between them. It also supports lazy loading, which can help improve performance by loading micro frontends only when needed.

Web Components

Web Components is a set of web platform APIs that allow developers to create reusable components that can be used across different frameworks and libraries. Web Components include custom elements, shadow DOM, and HTML templates. Custom elements allow developers to define new HTML tags, while shadow DOM allows developers to encapsulate the styles and behaviour of a component. HTML templates allow developers to define a reusable piece of markup that can be stamped out multiple times.

Module Federation

Module Federation is a technology introduced by webpack 5 that allows developers to dynamically load and share code across different micro frontends. Module Federation can help reduce duplication and improve performance by allowing micro frontends to share code and resources. It also provides a way for micro frontends to communicate with each other, which can be useful for passing data and events between micro frontends.

OpenComponents

OpenComponents is a micro frontend technology that allows developers to create reusable UI components that can be shared across different applications and teams. OpenComponents provides a set of tools for building, testing, and deploying components. It also supports lazy loading and caching, which can help improve performance by loading components only when needed.

Bit

Bit is a popular open-source tool for building and sharing reusable components across different projects and teams. Bit supports multiple frontend frameworks, including React, Angular, and Vue, and allows developers to share components across different micro frontends. Bit provides a set of tools for building, testing, and publishing components, and integrates with popular development tools like GitHub and npm.

These are just a few examples of the micro frontend technologies available in the market today. Each technology has its strengths and weaknesses, and developers should choose the technology that best suits their needs based on factors such as the size and complexity of their application, the development team's experience and expertise, and the project's requirements and constraints.

How to share code between two frontends?

For this example, I choose webpack 5 Module Federation feature. Before starting if you have no prior experience I would recommend following the steps for setting up a project with webpack.

First, in your webpack.config.js file for your host application, you would define a new plugin for module federation:

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

module.exports = {
  // ...
  plugins: [
    new HtmlWebpackPlugin(),
    new ModuleFederationPlugin({
      name: 'host',
      remotes: {
        remote: 'remote@http://localhost:3001/remoteEntry.js',
      },
    }),
  ],
};

In this example, we're defining a new module federation plugin that sets the name of our host application to host. We're also defining a remote micro frontend called remote and specifying its URL as localhost:3001/remoteEntry.js. This will allow our host application to load and use code from the remote micro frontend.

Next, in the webpack.config.js file for the remote micro frontend, we would define a new plugin for module federation:

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

module.exports = {
  // ...
  plugins: [
    new HtmlWebpackPlugin(),
    new ModuleFederationPlugin({
      name: 'remote',
      exposes: {
        './Button': './src/Button',
      },
    }),
  ],
};

In this example, we're defining a new module federation plugin that sets the name of our remote micro frontend to remote. We're also exposing a new component called Button from the src/Button file in our remote micro frontend.

Finally, in our host application, we can load the Button component from the remote micro frontend using the following code:

import React from 'react';
import ReactDOM from 'react-dom';
import Button from 'remote/Button';

ReactDOM.render(
  <Button />,
  document.getElementById('root')
);

In this example, we're importing the Button component from the remote micro frontend and using it in our host application. Thanks to module federation, our host application can seamlessly load and use code from the remote micro frontend without having to manually include any scripts or dependencies. This can help reduce duplication and improve performance by allowing micro frontends to share code and resources.

Micro frontends: To Use or Not to Use?

While micro frontends offer a lot of benefits, they may not be the best solution for every situation. Here are some factors to consider when deciding whether to use micro frontends or not:

When to use micro frontends:

  • Your front-end application is large and complex, making it difficult to manage and scale as a monolith.

  • Your development team is large and diverse, with different teams responsible for different parts of the application.

  • Your frontend application is composed of multiple, loosely-coupled components that can be easily separated into micro frontends.

  • You want to make your frontend application more modular, allowing you to quickly update and deploy individual components without affecting the entire application.

When not to use micro frontends:

  • Your frontend application is small and simple, making it easy to manage and scale as a monolith.

  • Your development team is small and tightly knit, with the ability to work collaboratively on the same codebase.

  • Your frontend application is highly integrated and tightly coupled, making it difficult to separate into individual micro frontends.

  • You don't have the resources or infrastructure to support multiple micro frontends.

Ultimately, the decision to use micro frontends or not will depend on the unique needs and goals of your project. While micro frontends can provide many benefits, it's important to carefully evaluate whether they are the right solution for your specific use case.

Conclusion

In conclusion, micro frontends can be a game changer for front-end development. By breaking down monolithic frontend applications into smaller, more manageable pieces, teams can work more efficiently and effectively, while improving performance and user experience. However, like any new technology, there are challenges and best practices to consider when adopting micro frontends. It's important to carefully plan and implement your micro frontends, while also keeping an eye on the bigger picture of your overall application architecture. With the right approach, micro frontends can help you build better, more scalable frontend applications that are ready to meet the demands of the modern web.