In our previous post, we walked through setting up a Nx monorepo containing a React web app, a Node.js API, and a React Native mobile app. In this post, we'll achieve the same setup using Lerna as our monorepo tool of choice.
Getting Started with the Monorepo
Start by creating a new directory for your monorepo, navigating into it, and initializing Lerna. This sets up the foundational structure for your project, including the necessary configuration files and a packages folder where your future sub-projects will reside.
mkdir Lerna
cd Lerna
npx lerna init
Setting Up the React Website
Next, we'll create a packages directory (if it doesn't already exist), navigate into it, and scaffold a new Vite project. This is where we'll add individual packages or apps managed by Lerna.
mkdir packages
cd packages
npm create vite@latest
Now, navigate into your new project directory (for example, website), install all required dependencies, and launch the development server to start building and previewing your app in real time.
cd website
npm install
npm run dev
Setting Up the Node Backend
Run the following commands:
cd ../
mkdir api
cd api
npm init
These commands move you up one directory level, create a new api folder, and enter it. Running npm init then initializes a new Node.js project, allowing you to configure your API package from scratch. This is the foundation for building a clean, modular Node.js REST API, following best practices for project organization and scalability.
Create a new file in the packages/api folder named index.js and paste the following code in it. This is a basic express server.
import express from 'express';
const app = express();
const PORT = 3001;
app.get('/', (_req, res) => {
res.send('Hello from the API!');
});
app.listen(PORT, () => {
console.log(`API listening on port ${PORT}`);
});
Now add scripts and packages in the package.json file to run the project. The final package.json file will look like this.
{
"name": "api",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "nodemon index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^5.1.0"
},
"devDependencies": {
"nodemon": "^3.1.10"
}
}
Run npm install
command to install the packages.
Run npm run dev
to start the api.
Setting Up the Bare React Native App
To set up a bare React Native project as a package within your Lerna monorepo using npm workspaces, follow these steps:
cd packages
npx @react-native-community/cli@latest init mobileApp
These commands navigate into your packages directory and initialize a new bare React Native project named mobileApp.
After initializing your React Native project, you need to install the native iOS dependencies using CocoaPods. This step is essential for the iOS part of your React Native app to work correctly.
cd mobileApp/iOS
pod install
Once you have installed the CocoaPods dependencies, you’re ready to start your React Native development server and launch the app on the iOS simulator.
cd ../
npm run start
npm run ios
Resolving Git Submodule Errors
Now that the app is up and running, it's time to commit your changes.
However, there's a small issue with the starter template—it initializes a Git repository inside the newly created apps/mobileApp folder. To get ride of that git submodule, from the root folder:
rm -rf apps/mobileApp/.git
git add .
git commit -m "create mobileApp"
We now have a working mobile app located in the apps folder, fully integrated into the monorepo with a clean Git setup.
Conclusion
By following these steps, you’ve successfully set up a scalable monorepo using Lerna and npm workspaces, and added both web (Vite), API (Node.js), and mobile (React Native) projects under a single repository. This unified workflow streamlines dependency management, code sharing, and collaboration across your entire stack. Whether you’re building for web, API, or mobile, this monorepo approach will help you stay organized, boost productivity, and simplify project maintenance as your codebase grows. Happy coding!
You can find all the code in the Github Repo.
Top comments (1)
Helpful and easy to understand!
Some comments may only be visible to logged-in visitors. Sign in to view all comments.