DEV Community

Cover image for Setting Up the Shell Project for React Micro Frontends
Aemarajan S
Aemarajan S

Posted on

Setting Up the Shell Project for React Micro Frontends

As frontend apps grow, micro frontend architecture helps divide responsibilities across smaller apps — making them easier to scale and maintain. If you’re new to this concept, check out our comparison of Monolithic vs Micro Frontends to understand the benefits and differences.

In this guide, we’ll set up the foundation: the Shell Project — the main container that will host and load other micro frontends dynamically using Module Federation.

By the end of this post, you'll have a fully running Shell ready to consume Micro Frontends.

Step 1: Create a React App for the Shell

Before we dive into the world of micro frontends, we need a central hub — the Shell application — that will host and control the overall layout and communication between different micro apps.

We’ll begin by creating a basic React app using Create React App (CRA), which gives us a fast and reliable boilerplate to start coding right away.

npx create-react-app shell
Enter fullscreen mode Exit fullscreen mode

This command will:

  • Scaffold a new React project named shell
  • Set up Webpack, Babel, and a development server internally (which we’ll soon override)
  • Create a project structure with folders like src, public, and node_modules
shell/
├── node_modules/
├── public/
│   └── index.html
├── src/
│   ├── App.js
│   ├── index.js
├── package.json
└── ...
Enter fullscreen mode Exit fullscreen mode

Step 2: Install and Configure html-webpack-plugin

Now that our React shell project is ready, we’re going to prepare it for Module Federation. To do this, we need more control over the build process — and that means customizing Webpack.

One of the first plugins we’ll use is html-webpack-plugin. This plugin helps Webpack generate the final index.html file and automatically injects the correct script tags for our bundled JavaScript.

npm install --save-dev html-webpack-plugin
Enter fullscreen mode Exit fullscreen mode

Step 3: Create and Configure webpack.config.js

Now that we’ve installed the necessary Webpack plugins, let’s set up the actual configuration.

By default, Create React App hides all the Webpack setup. But since we’re building a Micro Frontend Shell, we need to take full control. So we’ll create our own webpack.config.js and tell Webpack how to build and serve our project.

Inside your project’s root directory, create a new file called:

webpack.config.js
Enter fullscreen mode Exit fullscreen mode

Paste in the following configuration:

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

module.exports = {
  entry: "./src/index.js",
  mode: "development",
  devServer: {
    port: 3000,
    historyApiFallback: true,
  },
  output: {
    publicPath: "http://localhost:3000/",
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-react"],
          },
        },
      },
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
  resolve: {
    extensions: [".js", ".jsx"],
  },
  plugins: [
    new ModuleFederationPlugin({
      name: "shell",
      remotes: {
        mfe1: "mfe1@http://localhost:3001/remoteEntry.js",
      },
      shared: {
        react: { singleton: true },
        "react-dom": { singleton: true },
        "react-router-dom": { singleton: true },
      },
    }),
    new HtmlWebpackPlugin({
      template: "./public/index.html",
    }),
  ],
};
Enter fullscreen mode Exit fullscreen mode

What does this configuration do?

This webpack.config.js file sets up the foundation for our micro frontend Shell app. Here's a quick breakdown:

  • entry: Tells Webpack where your app starts — src/index.js.
    devServer: Runs a local dev server on localhost:3000 and supports client-side routing.

  • output.publicPath: Ensures the app knows where to load assets from at runtime, especially important for Micro Frontends.

  • rules: Handles JavaScript/JSX files using Babel and styles using CSS loaders.

  • resolve.alias: Adds a shortcut (shared) for importing shared code (optional).

  • ModuleFederationPlugin: The core of our setup. It declares this app as the Shell. Connects to a remote micro frontend (mfe1). Shares common dependencies like React to avoid duplication

  • HtmlWebpackPlugin: Injects the final bundle into your HTML automatically.

Step 4: Bootstrap Your App for Module Federation

To keep things flexible — especially when using Module Federation — it's a good practice to separate your app startup logic into a separate file.

We’ll do that by creating a new file called bootstrap.js and moving our React app’s rendering logic there.

  • Create a bootstrap.js inside src/:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
reportWebVitals();
Enter fullscreen mode Exit fullscreen mode
  • Update index.js: Now, update index.js to just import this bootstrap file.
import('./bootstrap');
Enter fullscreen mode Exit fullscreen mode

Step 5: Clean Up index.html and App.js

Before we move on, let’s clean up the default files from Create React App. Removing the extra code keeps things simple and easier to manage.

  • Optimize public/index.html Remove the unnecessary comments and default metadata. Here’s a cleaner version:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="description" content="Micro Frontend Shell App" />
    <title>Shell App</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode
  • Simplify App.js Now clean up App.js by removing unnecessary styles and structure.
import React from "react";

function App() {
  return (
    <div>
      <h1>Welcome to the Shell App</h1>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Step 6: Run the Shell App

Everything is set! Now let’s run the shell app and make sure it's working.

npm start
Enter fullscreen mode Exit fullscreen mode

You should see the shell running at http://localhost:3000 with a simple greeting message.

Here's a quick preview of what it looks like in the browser:

Screenshot of React Micro Frontend Shell App running on http://localhost:3000 displaying

Great job! You've just built the foundation of a Micro Frontend Shell using Module Federation.

This is just the beginning — up next, you'll connect your first remote app and see it all come to life.

Keep building. The real magic is just ahead! 🚀

Top comments (0)