Monorepos lets you manage multiple repositories into one single repository but managing and publishing them can be very tedious as the repositories grow. Lerna is a powerful tool that can be used to manage and publish monorepos in Javascript/Typescript projects. Lerna is a fast, modern build system for managing and publishing multiple JavaScript/TypeScript packages from the same repository. In this article, we will see how we can set up a monorepo with Lerna and Npm workspaces. If you are interested in setting up a monorepo with Vite, Pnpm, and Typescript you can check out my previous blog . here Why use Lerna? To use monorepos well, you need a good monorepo tool, and Lerna is exactly that. Lerna is fast, widely used, and battle tested. Monorepos can have tens if not hundreds of packages, and managing all of them together can become very difficult. Lerna can rescue us in this situation by doing the heavy lifting of managing the tasks in different packages, versioning, code deployment, etc. Lerna has some great in-built features which make managing monorepos surprisingly easier. : Lerna gives us an out-of-the-box solution to run tasks inside multiple packages together using command. For example, Let's say you have 3 packages inside your monorepo and you want to run the script for all of them, with Lerna all you have to do is just run command from the root of your project and it will run the script inside each of your packages (You must have defined the script in package.json for all the projects respectively in order to make this work properly). Running tasks within multiple packages lerna run test npx lerna run test test test : When the workspace becomes very huge it is common for a new developer to face difficulty in understanding the hierarchy of the workspace and understand how different packages are linked together. Lerna uses to help visualize the workspace graph. Simply run and it will launch a project visualization graph on your browser. Visualize the workspace Nx npx nx graph You can check the complete list of Lerna features . here Who uses Lerna? Lerna is being used by many different teams including but not limited to: Jest Create React App Nx NestJS Project Setup Prerequisites To follow along, you must have installed in your system which I am assuming that you would already have. Other than that, some basic knowledge of Javascript/Typescript and React will help in understanding the code that we are going to write. Node Project Overview For the sake of this article, our monorepo will have two packages: : A shared library that can be used by multiple packages. common : A basic React app that will consume the package and will render the components on UI. client common Getting Started Let's start off by creating a new directory at your desired location. mkdir npm-lerna-monorepo Then, move inside your newly created directory and initialize a Lerna workspace. # npm-lerna-monorepo npx lerna init This command will do the following things: Create a file if it is not already present and add as a dev dependency. package.json lerna Create and configure a new file. lerna.json Configure npm workspaces inside . package.json Create a directory that will contain all our monorepo packages. packages ├── lerna.json ├── .gitignore ├── package.json └── packages Now, in order to use Typescript in our project, we need to install a few dependencies at the root level. npm i typescript @types/node -D Once the above dependencies are installed, create a common file that will be extended by all the other packages of our app. tsconfig.json { "compilerOptions": { "module": "commonjs", "declaration": false, "noImplicitAny": false, "removeComments": true, "noLib": false, "emitDecoratorMetadata": true, "experimentalDecorators": true, "target": "es6", "allowSyntheticDefaultImports": true, "sourceMap": true, "moduleResolution": "node", "lib": ["es6"] }, "exclude": ["node_modules"] } Now we can start creating our packages, to do that let's go inside the directory and create the package first. packages common npm create vite@latest common --template react-ts We should now have a package inside our directory, now let's move inside the directory and run to install all the required dependencies. common packages common npm install # npm-lerna-monorepo/packages/common npm install In order to use the base Typescript configuration that we've defined at the root level, we need to add the following snippet at the beginning of our inside the common package. tsconfig.json // npm-lerna-monorepo/packages/common/tsconfig.json { "extends": "../../tsconfig.json", ... } We will now go ahead and create a Button component and will export it so that it can be used by the other packages in our monorepo. // npm-lerna-monorepo/packages/common/src/components/Button.tsx interface ButtonProps { buttonText: string; } const Button = ({ buttonText }: ButtonProps) => { return ( <button>{buttonText}</button> ) } export default Button; Now export this Button component from file which will be our entry point. main.tsx // npm-lerna-monorepo/packages/common/src/main.tsx import Button from "./components/Button" export { Button } We will set as our entry point by setting the property in main.tsx main package.json Also, as per the common workspace naming convention of monorepos we'll change the name of the package to common @npm-lerna-monorepo/common // npm-lerna-monorepo/packages/common/package.json { "name": "@npm-lerna-monorepo/common", // Change the package name "private": true, "version": "0.0.0", "type": "module", "main": "./src/main.tsx", // Define the entrypoint file ... } We should now be able to import components from the package very easily after linking it with the package. common client Let's now create our package, for that we'll move inside the packages directory and run the following command: client # npm-lerna-monorepo/packages npm create vite@latest client --template react-ts Our project structure after running the above command should look somewhat like this: Let's update the of the client package now to extend the base Typescript configuration that we've defined at the root level. tsconfig.json To do that add the following line of code at the beginning of : client/tsconfig.json // npm-lerna-monorepo/packages/client/tsconfig.json { "extends": "../../tsconfig.json", ... } Now add the package as one of the dependencies for the package, we can add the common package using the name that we've defined in its file. common client package.json // npm-lerna-monorepo/packages/client/package.json { "name": "@npm-lerna-monorepo/client", // Updated the name ... "dependencies": { "react": "^18.2.0", "react-dom": "^18.2.0", "@npm-lerna-monorepo/common": "*" // Added common package ... }, We've also changed the name of the package according to the monorepos workspace naming convention. client Let's link both of our packages together by running from the root level. npm install # npm-lerna-monorepo npm install This will link both packages together and now we can easily import the Button component from the package and use it in our package. common client // npm-lerna-monorepo/packages/client/src/App.tsx import { Button } from "@npm-lerna-monorepo/common" const App = () => { return <Button buttonText="Hello world" /> } export default App; Run the dev server for package now. client # npm-lerna-monorepo/packages/client npm run dev Open on your favorite web browser and you should see a button rendered on the UI. localhost:5173 So we have successfully setup up our monorepo using Npm workspaces and Lerna and while you are in our local environment, any changes you will make to the package will immediately reflect on the . common client Hooray 🎉 You can find the complete code of the setup . here Conclusion In this article, we have seen how we can set up and manage a monorepo with Lerna and Npm workspaces. Though Lerna is a great tool, you don't need to include it in all of your monorepos it's mainly suitable for large applications where you have multiple packages that you need to manage simultaneously. While this article was majorly focused on the setup part, if you are interested in reading more about how we can use Lerna to build and publish our monorepos please let me know in the comments. I hope this blog could a little value to you. If you liked it please share it with those who might find it helpful and show some ❤️ to the article. You can also follow me on where I post more content on Javascript, React, Software Engineering, and other stuff. Twitter Also published . here