// Tutorial //

How To Manage Monorepos With Lerna

Published on June 29, 2022
Default avatar
By nimishbongale
Developer and author at DigitalOcean.
How To Manage Monorepos With Lerna

The author selected the Diversity in Tech Fund to receive a donation as part of the Write for DOnations program.

Introduction

Lerna is a tool for managing JavaScript projects with multiple packages. Lerna manages monorepos, which can hold projects containing multiple packages within itself.

Monorepos can be challenging to manage because sequential builds and publishing individual packages take a long time. Lerna provides features such as package bootstrapping, parallelized builds, and artifactory publication, which can aid you when managing monorepos. Lerna is beneficial for projects that share common dependencies.

In this tutorial, you will install Lerna, create a working directory, initialize a Lerna project, create a monorepo, bootstrap your packages, and add a dependency to all the packages.

Prerequisites

To complete this tutorial, you will need:

Step 1 — Installing Lerna and Initializing the Project

In this step, you will install Lerna and set up your project. With Lerna, you can manage common packages across your projects, which is helpful when working with monorepos.

Start by installing Lerna with the following command:

  1. npm i -g lerna

npm i will use npm to install the lerna package. The -g flag means that the lerna command is globally available via the terminal.

Note: If you run into permission errors, you may need to rerun the command with administrator access. Using sudo for non-root users should do the trick.

You can now change the directory into a location of your choice and create a sample working directory to house the Lerna project.

Run the following command to create your sample working directory:

  1. mkdir lerna-demo
  2. cd lerna-demo

You can now run init within your directory:

  1. lerna init

You will see the following output:

Output
... lerna notice cli v4.0.0 lerna info Initializing Git repository lerna info Creating package.json lerna info Creating lerna.json lerna info Creating packages directory lerna success Initialized Lerna files

The init command creates a lerna.json file. This file can be customized, though this tutorial will use the default state. This command also initializes a git repository and creates a package.json file and a packages/ directory.

In this step, you installed Lerna and initialized your project. Next, you will create the monorepo.

Step 2 — Creating the Monorepo

In this step, you will create the monorepo needed to work with Lerna. A monorepo is a repository containing a project (or multiple projects) and multiple packages. The folders and packages created here are necessary for the later stages of the tutorial.

Use the following commands to create the apple/ folder under the packages/ directory, then run npm init to set up the directory:

  1. mkdir apple
  2. cd apple
  3. npm init

You will see the following output for npm init within the apple/ directory:

Output
... ❯ npm init This utility will walk you through creating a package.json file. It only covers the most common items and tries to guess sensible defaults. See `npm help init` for definitive documentation on these fields and exactly what they do. Use `npm install <pkg>` afterward to install a package and save it as a dependency in the package.json file. Press ^C at any time to quit. package name: (apple) (ENTER) version: (1.0.0) (ENTER) description: (ENTER) entry point: (index.js) (ENTER) test command: (ENTER) git repository: (ENTER) keywords: (ENTER) author: (ENTER) license: (ISC) (ENTER) About to write to lerna-demo/packages/apple/package.json: { "name": "apple", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" } Is this OK? (yes) y

You can keep the default values. After creating and updating the apple/ folder, follow the same process to make folders for orange/ and banana/.

Now that you have the npm packages initialized with the npm init step, you can run the bootstrap command, which will run npm install in all your packages. Lerna’s bootstrap command installs package dependencies and links the packages together. Without bootstrapping your packages, the package dependencies will not satisfy, and you won’t be able to run any npm scripts across the project.

Run the following command to bootstrap your npm packages from your project root folder:

  1. lerna bootstrap

You’ll see the following output:

Output
... ❯ lerna bootstrap lerna notice cli v4.0.0 lerna info Bootstrapping 3 packages lerna info Symlinking packages and binaries lerna success Bootstrapped 3 packages

In this step, you set up the monorepo with three folders and bootstrapped your packages to the directory. Next, you will add dependencies to the packages in your monorepo.

Step 3 — Installing Packages in the Monorepo

In this step, you will use Lerna to install a sample package in your monorepo. Lerna can help you manage packages and dependencies across projects within the monorepo.

To add a package to your project, use the lerna exec command to execute a shell command:

  1. lerna exec npm i lite-server --parallel

You are using lite-server as an example since it is a lightweight package. You might consider adding other packages with this method, depending on your project requirements.

The --parallel flag signals the build to run simultaneously, saving time during the compilation process.

The expected output will look like this:

Output
... ❯ lerna exec npm i lite-server --parallel lerna notice cli v4.0.0 lerna info Executing command in 3 packages: "npm i lite-server" apple: added 179 packages, and audited 180 packages in 12s apple: 6 packages are looking for funding apple: run `npm fund` for details apple: found 0 vulnerabilities orange: added 179 packages, and audited 180 packages in 12s orange: 6 packages are looking for funding orange: run `npm fund` for details orange: found 0 vulnerabilities banana: added 179 packages, and audited 180 packages in 12s banana: 6 packages are looking for funding banana: run `npm fund` for details banana: found 0 vulnerabilities lerna success exec Executed command in 3 packages: "npm i lite-server"

A lerna success message at the end of the output log indicates that the command ran successfully and that you have installed the lite-server package in each of the project folders.

In this step, you installed a dependency in all your packages. Next, you will run a script in your packages.

Step 4 — Running Scripts

In this step, you will run scripts that customize the build for your packages. You can use lerna run <cmd> to execute the npm run <cmd> in all of your packages. The npm run command runs the specified npm script in the package.json file.

As an example, run the test script that comes bundled with the packages that you added in Step 2:

  1. lerna run test --no-bail

Passing a --no-bail flag informs Lerna to run the script for all the packages, even if a particular package script has an error.

You will see the following output:

Output
... lerna notice cli v4.0.0 lerna info Executing command in 3 packages: "npm run test" lerna info run Ran npm script 'test' in 'apple' in 0.2s: > apple@1.0.0 test > echo "Error: no test specified" && exit 1 Error: no test specified lerna info run Ran npm script 'test' in 'banana' in 0.2s: > banana@1.0.0 test > echo "Error: no test specified" && exit 1 Error: no test specified lerna info run Ran npm script 'test' in 'orange' in 0.2s: > orange@1.0.0 test > echo "Error: no test specified" && exit 1 Error: no test specified lerna ERR! Received non-zero exit code 1 during execution lerna success run Ran npm script 'test' in 3 packages in 0.2s: lerna success - apple lerna success - banana lerna success - orange

With this command, you ran the test script for your packages. Since you have not defined any tests, you receive a default output of "Error: no test specified". You did receive the exit code 1 notice, but passing in the --no-bail flag means that your scripts run without issue. If you don’t pass in the --no-bail flag, then Lerna will stop the execution after the step fails for the first package.

Conclusion

In this article, you learned how to manage monorepos with Lerna. You can now use Lerna to automate tasks requiring similar changes across all packages. You also passed special flags like --no-bail and --parallel to customize your builds. For more information, visit the official Lerna documentation page.

To make your package globally available, you can publish your packages to an artifactory of your choice. npmjs is a public artifactory where you can push your packages. The lerna publish command can push all your packages at once. A lerna success message means you have successfully uploaded your packages to the artifactory.


Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in our Questions & Answers section, find tutorials and tools that will help you grow as a developer and scale your project or business, and subscribe to topics of interest.

Sign up
About the authors
Default avatar
Developer and author at DigitalOcean.

Default avatar
Technical Editor

Still looking for an answer?

Was this helpful?
Leave a comment

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!