· Documentation  · 4 min read

Microfrontends with React Native

Microfrontends are a powerful way to build scalable and maintainable mobile apps. This article shows how to use React Native to create modular components that can be developed and tested independently. This approach improves workflow, supports parallel development, and ensures code reusability.

Microfrontends are a powerful way to build scalable and maintainable mobile apps. This article shows how to use React Native to create modular components that can be developed and tested independently. This approach improves workflow, supports parallel development, and ensures code reusability.

Microfrontends with React Native

Introduction

In my last project, the use of microfrontends with React Native was suggested, something I had never worked with before. During my research, I found several ways to implement it, but the one that made the most sense was from the following video:

Microfrontends with React Native

The idea is to divide the modules into packages, where each one exports its components and screens, allowing each module to be tested separately.

Getting Started

First, you need to create a “root” React Native project that will receive the modules.

Step 1: Create the Root Project

Create a new React Native project:

npx react-native init RootApp
cd RootApp

Step 2: Create and Configure Modules

Let’s start creating each module. First, let’s install the react-native-builder-bob library:

npx create-react-native-library @example/menu

Step 3: Create the Menu Component

Inside the @example/menu module, create a Menu.tsx component:

// @example/menu/src/Menu.tsx
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

const Menu = () => {
  return (
    <View style={styles.container}>
      <Text style={styles.text}>Menu Component</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  text: {
    fontSize: 20,
  },
});

export default Menu;

Step 4: Export the Component

In the module’s index.ts file, export the Menu component:

// @example/menu/src/index.ts
export { default as Menu } from './Menu';

Step 5: Import and Use in the Root App

Now, import the @example/menu library into your root app and use the component:

// RootApp/App.tsx
import React from 'react';
import { SafeAreaView, StyleSheet } from 'react-native';
import { Menu } from '@example/menu';

const App = () => {
  return (
    <SafeAreaView style={styles.container}>
      <Menu />
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});

export default App;

Benefits of Testing Components Separately

One of the great advantages of using microfrontends is the ability to test components in isolation. This brings several benefits:

  1. Ease of Debugging: Testing components separately makes it easier to identify bugs, as you can isolate the problem in a specific module.
  2. Parallel Development: Different teams can work on different modules simultaneously, speeding up development.
  3. Code Reusability: Well-tested components can be reused in different parts of the application or even in other projects.

Creating a Test App for Each Module

It’s also possible to create a React Native app within each module to test these screens without having to integrate the library with the root app. This allows for even more isolated testing and development.

For example, you can create a test app inside the @example/menu module:

cd @example/menu
npx react-native init TestApp
cd TestApp

Then, you can use the Menu component in this test app:

// @example/menu/TestApp/App.tsx
import React from 'react';
import { SafeAreaView, StyleSheet } from 'react-native';
import Menu from '../src/Menu';

const App = () => {
  return (
    <SafeAreaView style={styles.container}>
      <Menu />
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});

export default App;

Sharing Libraries

Even with the division into modules, all libraries and dependencies, such as Firebase, Redux, and others, will be shared by the root app. This means you can configure these libraries in the root project and use them in any module, ensuring consistency and avoiding code duplication.

For example, if you configure Firebase in the root project, you can use it in any module without needing to configure it again:

// RootApp/App.tsx
import React from 'react';
import { SafeAreaView, StyleSheet } from 'react-native';
import { Menu } from '@example/menu';
import firebase from 'firebase/app';
import 'firebase/auth';

// Firebase Configuration
const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
  appId: "YOUR_APP_ID"
};

if (!firebase.apps.length) {
  firebase.initializeApp(firebaseConfig);
}

const App = () => {
  return (
    <SafeAreaView style={styles.container}>
      <Menu />
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});

export default App;

Conclusion

With these steps, you can start implementing microfrontends in your React Native project. Each module can be developed and tested separately, making your application easier to maintain and scale. Additionally, libraries and dependencies configured in the root project will be shared by all modules, ensuring consistency and efficiency.


Back to Blog

Related Posts

View All Posts »
Automated Testing in React Native

Automated Testing in React Native

Automated testing is crucial for maintaining the stability and quality of React Native applications. This article delves into the essential techniques and tools for effective testing.