JavaScript Development Space

Mastering Monorepos - Creating a Monorepo Using Npm, Yarn, Pnpm, and Bun Workspaces

Add to your RSS feed23 September 20245 min read
Mastering Monorepos - Creating a Monorepo Using Npm, Yarn, Pnpm, and Bun Workspaces

In this guide, we will explore how to set up a monorepo that combines NestJS(server) and ReactJS(client), leveraging different package managers: npm, yarn, pnpm, and bun. Monorepos offer a way to manage multiple projects in a single repository, enhancing collaboration and simplifying dependency management. Let's dive into the steps!

What You Will Learn

  • Understanding monorepos and their benefits.
  • Setting up a monorepo structure.
  • Configuring NestJS and ReactJS within the monorepo.
  • Managing dependencies with npm, Yarn, pnpm, and Bun workspaces.

1. Understanding Monorepos

Monorepos allow you to manage multiple projects within a single repository, promoting code sharing, consistent tooling, and streamlined development processes. This structure is especially beneficial for large applications or organizations with several related projects.

2. Setting Up the Monorepo Structure

Step 1: Create a new folder

Create a new directory for your monorepo and initialize it.

mkdir monorepo && cd monorepo

Step 2: Initialize the Monorepo

npm init -y

Next, add server and client folders, and initialize them.

npm init -y -w packages/server -w packages/client

This will create 2 new folders with package.json file, and 2 folders: server and client inside the node_modules directory.

#pnpm

pnpm init -y
pnpm init -y -w packages/server -w packages/client

#yarn

yarn init

pnpm init -y workspaces focus packages/server workspaces focus packages/client

#Bun

bun init
cd packages/server && bun init -y
cd packages/client && bun init -y

Step 3: Installing Workspace Dependencies

Install the dependencies for all packages listed in the workspace configuration.

npm install

#pnpm

pnpm install

#yarn

yarn install

#Bun

bun install

Step 4: Listing Dependencies Across Workspaces

Display the dependencies for all workspaces.

npm ls

#pnpm

pnpm install
pnpm list

A pnpm workspace must have a pnpm-workspace.yaml file in its root.

touch pnpm-workspace.yaml

Add this code:

dash
1 - 'packages/client/*'
2 - 'packages/server/*'

#yarn

yarn install
yarn workspaces list

#Bun

Add this code to package.json:

js
1 "workspaces": [
2 "packages/client",
3 "packages/server",
4 ]

then

bun pm ls

3. Install the ReactJS as client

We will use vite for creating a new react app with typescript

npm create vite@latest . -w packages/client
bash
1 √ Current directory is not empty. Please choose how to proceed: » Remove existing files and continue
2 √ Select a framework: » React
3 √ Select a variant: » TypeScript + SWC

The current structure of your project now looks like this:

Initialize structure

pnpm

In pnpm, you will need to open a specific package

cd packages/client
pnpm create vite@latest .

yarn

yarn workspace client create vite@latest . -w packages/client

Bun

cd packages/client
bun create vite@latest .

4. Install the NestJS as server

Initialize the NestJS instance

npm i --save @nestjs/core @nestjs/common rxjs reflect-metadata @nestjs/platform-express -w server

pnpm

cd packages/server
nest new

Don't forget to rename the names of the packages.

yarn

cd packages/server
nest new

Bun

cd packages/client
nest new

5. Create separate NestJs project

We need to create a new project to copy the starter files from it.

nest new nest-demo

Now copy all files from the root directory as well as the src directory.

Copy NestJS file

then run

npm install

6. Test the backend and frontend

Don't forget to rename the names of package.json to server, or client.

Let's test the packages...

ReactJS test

npm -w client run dev

NestJS test

npm -w server run start:dev

pnpm

cd packages/client && pnpm run dev
cd packages/server && pnpm start:dev

yarn

cd packages/client && yarn dev
cd packages/server && yarn start:dev

Bun

cd packages/client && bun run dev
cd packages/server && bun run start:dev

7. Install server on client side

We will connect to the server by installing the server to the client as a dependency

npm -w client install server@*

or add the dependency to the package.json file

js
1 "dependencies": {
2 "react": "^18.3.1",
3 "react-dom": "^18.3.1",
4 "server": "*"
5 },

then run again

npm run install

This way, you can utilize shared types and interfaces.

pnpm

cd packages/client && pnpm install server@*

yarn

cd packages/client && yarn add server@*

Bun

cd packages/client && bun install server@*

Connect the frontend to the server

Enable Cors in NestJS

Add this code to main.ts file on NestJS server

js
1 async function bootstrap() {
2 const app = await NestFactory.create(AppModule);
3 app.enableCors();
4 await app.listen(3000);
5 }

Now run the backend:

npm -w server run start:dev

Connect client to server

First change the App.tsx file

js
1 import { useEffect, useState } from 'react';
2 import './App.css';
3
4 function App() {
5 const [data, setData] = useState('');
6
7 useEffect(() => {
8 const getData = async () => {
9 const response = await fetch('http://localhost:3000');
10 const data = await response.text();
11 setData(data);
12 };
13 getData();
14 }, []);
15
16 return <>{data}</>;
17 }
18
19 export default App;

We use the response.text() method because it returns a string instead of JSON.

Now run

npm run dev -w client
Final result

Resources

npm workspaces | pnpm workspaces | yarn workspaces | bun workspaces

Conclusion

By setting up a monorepo with NestJS and ReactJs, you streamline your development process, making it easier to share code and manage dependencies. This setup can significantly enhance productivity, especially in larger projects. Explore further by integrating shared libraries or tools to maximize the benefits of your monorepo structure!

Creating a monorepo using npm, Yarn, pnpm, or Bun workspaces provides an efficient way to manage multiple projects within a single repository. By centralizing dependencies, simplifying code sharing, and enhancing collaboration across teams, monorepos streamline development workflows. Each package manager offers unique strengths, allowing you to choose the tool that best fits your project needs. Whether you’re working with small or large-scale applications, adopting a monorepo structure can improve productivity, consistency, and maintainability in your codebase.

JavaScript Development Space

© 2024 JavaScript Development Space - Master JS and NodeJS. All rights reserved.