DEV Community

Cover image for Monorepos!! Nx vs Turborepo vs Lerna – Part 3: Lerna
Suryansh Sharma
Suryansh Sharma

Posted on

Monorepos!! Nx vs Turborepo vs Lerna – Part 3: Lerna

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
Enter fullscreen mode Exit fullscreen mode

lerna init folder structure

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

react preview

Setting Up the Node Backend

Run the following commands:

cd ../
mkdir api
cd api
npm init
Enter fullscreen mode Exit fullscreen mode

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}`);
});
Enter fullscreen mode Exit fullscreen mode

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"
  }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

mobileApp preview

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"
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
priyaranjan25 profile image
Priyaranjan Kumar

Helpful and easy to understand!

Some comments may only be visible to logged-in visitors. Sign in to view all comments.