*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

lerna illustration for: 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:

				
					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:

				
					mkdir lerna-demo
cd lerna-demo
				
			

You can now run init within your directory:

				
					lerna init
				
			

You will see the following output:

				
					[secondary_label 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:

				
					mkdir apple
cd apple
npm init
				
			

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

				
					[secondary_label 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:

				
					lerna bootstrap
				
			

You'll see the following output:

				
					[secondary_label 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:

				
					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:

				
					[secondary_label 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:

				
					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:

				
					[secondary_label 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:

&gt; apple@1.0.0 test
&gt; echo "Error: no test specified" &amp;&amp; exit 1

Error: no test specified
lerna info run Ran npm script 'test' in 'banana' in 0.2s:

&gt; banana@1.0.0 test
&gt; echo "Error: no test specified" &amp;&amp; exit 1

Error: no test specified
lerna info run Ran npm script 'test' in 'orange' in 0.2s:

&gt; orange@1.0.0 test
&gt; echo "Error: no test specified" &amp;&amp; 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.