From Monolithic App to Micro Frontends

How to start converting a legacy frontend application to micro frontends

Chameera Dulanga
Bits and Pieces

--

The micro frontends architecture, being inspired by microservices, is a component-driven approach to building the frontend where each component or feature of the frontend is a self-contained, independently deployable module, worked upon by independent dev teams.

This architecture enables developers to build and update individual components separately without affecting other components or features in the frontend, making the application more scalable, modular, and flexible and at the same time improving collaboration among developers. The micro frontends architecture is a perfect method for breaking down large monolithic applications into nimble, independent units.

Transitioning an established monolithic application into micro frontends, however, poses a considerable challenge, demanding substantial time and effort.

Various crucial aspects must be carefully considered, such as identifying and isolating individual UI components, establishing efficient communication mechanisms, ensuring seamless data flow, conducting meticulous code refactoring, and devising effective deployment strategies.

Amidst these obstacles, the potential rewards offered by micro frontends make every ounce of exertion worthwhile, particularly for organizations keen on revitalizing and modernizing their applications.

Treating the micro frontends architecture like composable building blocks is key, and it’s made easier with a tool like Bit which allows your teams to independently version, document, test, publish, and share individual components, that can be reused across multiple micro frontends, making it easier to maintain and update your micro frontend architecture.

So, in this article, I will take you through the steps of creating and using micro frontends in an existing application using Bit without a major migration effort.

Converting a Monolithic React app to Micro Frontends

In this instance, I will develop a movie website, as depicted below.

To access the React monolithic application mentioned above, you can find it conveniently in my GitHub repository. In the following steps, I will transform it into micro frontends using Bit.

Step 1 — Selecting the first component to migrate

When embarking on the migration process, the initial selection of the component to convert holds paramount importance as it sets the stage for subsequent steps. Opting for a component with minimal dependencies or none proves advantageous, as it allows for a smoother transition without encountering significant challenges right from the outset.

In this example, I selected the src/components/Banners component as the first to migrate.

Step 2 — Initialize a Bit workspace within the React application

To begin the migration process, the first step is to install Bit into your local development environment. If you dont have a Bit account, you can sign up with Bit for free.

Once installed, you can leverage Bit CLI commands to initialize a Bit workspace within the React application.

Open a command line interface in the application’s root directory and run bit init command to initialize a Bit workspace. It will create a new file named workspace.jsonc in the project root.

If you need, you can change the workspace name and the scope name using workspace.jsonc file. In this case, I have changed the workspace name to microfrontends and the scope name to chameera.microfrontends, where chameera is my organization name.

Step 3 — Create a new React component using Bit

You must create a new React application using Bit to maintain the micro frontends.

bit create react-app banner --aspect teambit.react/react

The Bit CLI command below will create a new directory named microfrontends in the project root and a new React component named banner within that folder.

Then, update the microfrontends/banner/app.tsx file using content from src/components/Banners/Banner.jsx file.

import React, { useState } from 'react'
import {
Box,
IconButton,
useBreakpointValue,
Stack,
Container,
} from '@chakra-ui/react'
import { BiLeftArrowAlt, BiRightArrowAlt } from 'react-icons/bi'
import Slider from 'react-slick'

export type BannerProps = {
cards: Card[]
}

type Card = {
id: string
image: string
}

type SliderType = {
slickPrev: () => void
slickNext: () => void
}

// eslint-disable-next-line @typescript-eslint/no-use-before-define
Banner.defaultProps = {
cards: [],
}

const slidersSettings = {
dots: true,
arrows: false,
fade: true,
infinite: true,
autoplay: true,
speed: 500,
autoplaySpeed: 3000,
slidesToShow: 1,
slidesToScroll: 1,
}

export function Banner({ cards }: BannerProps) {
const [slider, setSlider] = useState<SliderType | undefined>(undefined)

const top = useBreakpointValue({ base: '90%', md: '50%' })
const side = useBreakpointValue({ base: '30%', md: '40px' })

return (
<Box position="relative" height="650px" width="full" overflow="hidden">
<link
rel="stylesheet"
type="text/css"
charSet="UTF-8"
href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.css"
/>
<link
rel="stylesheet"
type="text/css"
href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick-theme.min.css"
/>
<IconButton
aria-label="left-arrow"
variant="ghost"
position="absolute"
left={side}
top={top}
transform="translate(0%, -50%)"
zIndex={2}
onClick={() => slider?.slickPrev()}
<BiLeftArrowAlt size="40px" />
</IconButton>
<IconButton
aria-label="right-arrow"
variant="ghost"
position="absolute"
right={side}
top={top}
transform="translate(0%, -50%)"
zIndex={2}
onClick={() => slider?.slickNext()}
<BiRightArrowAlt size="40px" />
</IconButton>
<Slider {...slidersSettings} ref={(sliderEl) => setSlider(sliderEl)}>
{cards.map((card) => (
<Box
key={card.id}
height="2xl"
position="relative"
backgroundPosition="center"
backgroundRepeat="no-repeat"
backgroundSize="cover"
backgroundImage={url(${card.image}) }
<Container size="container.lg" height="600px" position="relative">
<Stack
spacing={6}
border="1px soild red"
w="full"
position="absolute"
color="white"
top="15%"
transform="translate(0, -50%)"
/>
</Container>
</Box>
))}
</Slider>
</Box>
)
}

Now, running the bit show banner command will show you all the details about this new component, including name, scope, files, dev dependencies, peer dependencies, etc.

If you need, you can add more dependencies to these components using Bit CLI. For example, using the command below, I have added 3 new dependencies for the banner component.

bit deps set banner @emotion/styled @emotion/react framer-motion

Step 4 — Update the new component files

1. banner.compositions.tsx

The composition file is crucial in creating diverse component variations, serving as a valuable tool for testing, visualization, and enhancing discoverability. It empowers developers by comprehensively understanding how a component appears and behaves in different potential use cases. This insightful feature enables developers to deliver components that seamlessly integrate and function as intended when consumed by other components or projects.

In this example, I have updated the banner.composition.tsx file with ChakraProvider and images to test the banner component.

import React from 'react'
import { ChakraProvider } from '@chakra-ui/react
import { Banner } from './app'
import { cards } from './data/cards

export const BannerBasic = () => (
<ChakraProvider>
<Banner cards={cards} />
</ChakraProvider>
)

I have also created a new file named banner/data/cards.ts and updated it with the code below to provide images to the composition file.

export const cards = [
{
id: '1',
image:
'https://nameh-dhiman.github.io/Apple-TV-Clone-Project.github.io/Images/Tedd%20Lasso.jpg',
},
{
id: '2',
image:
'https://9to5mac.com/wp-content/uploads/sites/6/2022/02/sky-is-everywhere-how-to-watch.jpg?quality=82&strip=all',
},
{
id: '3',
image: 'https://flxt.tmsimg.com/assets/p17586756_b_h8_af.jpg',
},
{
id: '4',
image:
'https://is1-ssl.mzstatic.com/image/thumb/Features126/v4/93/50/f4/9350f4f6-4c50-f6a5-6976-446a5333b265/U0ZfVFZBX1dXX0RlYXItUzItQ29taW5nX1Nvb24tQnJpY2subHNy.lsr/1478x832fe.webp',
},
{
id: '5',
image:
'https://www.apple.com/tv-pr/articles/2022/01/global-hit-series-the-morning-show-starring-and-executive-produced-by-jennifer-aniston-and-reese-witherspoon-renewed-for-season-three/images/big-image/big-image-01/011021_The_Morning_Show_Renewed_Season_Three_Big_Image_01_big_image_post.jpg.large.jpg',
},
]

2. banner.app-root.tsx

banner.app-root.tsx file is responsible for mounting React components to the root of the HTML. You need to update it with the same code used for composition.

3. index.ts

export { Banner } from './app';

Now, you can start the local Bit server using the bit start command and see the banner component in action.

Step 5 — Integrate micro frontend in the existing app

Since you now have a working micro frontend for the banner component, you can replace the existing banner component of the monolith with the micro frontend. You only need to import the banner component from the Bit workspace instead of the local codebase.

In this case, you must update the import lines of src/pages/Home.jsx component as follow:

import { Box } from '@chakra-ui/react'
// import { Banner } from '../components/Banners/Banner'
import { Banner } from '@chameera/microfrontends.banner'
import { HomeContent } from '../components/HomeContent/HomeContent'
import { Footer } from '../components/Footer/Footer'
import { cards } from '../db'

Then, run npm start command to start the application. You will get the same application as the previous one without any issues. But this time, a micro frontend is used for the banner component.

In addition, you can run the micro frontend isolated from the application using the commands below:

bit use banner

bit run banner

Step 6 — Exporting the micro frontend for other teams to use

Bit allows you to export the components to a remote scope in bit.cloud making them available for other developers and teams for their applications.

First, you must log in to your account using the command below:

bit login

Then, tag the component with a semantic release version using the command below. You can find more about Bit tag command here.

bit tag -m "banner-microftontend"

Finally, export the component using the following command.

bit export

Once the component is exported, you can access and share it through the Bit scope URL.

Conclusion

To summarize, micro frontends have become immensely popular in modern web application development because of their ability to break down large applications into smaller, independent components. This approach brings numerous benefits, such as improved scalability, flexibility, and collaboration among development teams. Although converting an existing monolithic application into micro frontends can present challenges, the potential advantages make it worthwhile for organizations seeking to modernize their applications.

This article provides a comprehensive guide on migrating a React monolith to micro frontends using Bit. With Bit, developers can conveniently develop and test micro frontends within an integrated development environment that offers individual source files, dependencies, metadata, and configuration.

In addition to the build time micro frontend discussed in this article, Bit supports runtime micro frontend integration through module federation. You can find more about it in the below video on Bit’s YouTube channel.

Thank you for taking the time to read this guide. I truly appreciate your engagement and wish you great success in your micro frontend migration endeavors. Happy coding, and may your applications flourish in the world of micro frontends!

Build composable React apps with reusable components, just like Lego

Bit is an open-source toolchain for the development of composable software.

With Bit, you can develop any piece of software — a modern web app, a UI component, a backend service or a CLI script — as an independent, reusable and composable unit of software. Share any component across your applications to make it easier to collaborate and faster to build.

Join the 100,000+ developers building composable software together.

Get started with these tutorials:

→ Micro-Frontends: Video // Guide

→ Code Sharing: Video // Guide

→ App Modernization: Video // Guide

→ Monorepo: Video // Guide

→ Microservices: Video // Guide

→ Design System: Video // Guide

--

--