# lerna **Repository Path**: mirrors_atlassian/lerna ## Basic Information - **Project Name**: lerna - **Description**: :dragon: A tool for managing JavaScript projects with multiple packages. - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-08-08 - **Last Updated**: 2026-01-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README
A tool for managing JavaScript projects with multiple packages.
## About Splitting up large codebases into separate independently versioned packages is extremely useful for code sharing. However, making changes across many repositories is *messy* and difficult to track, and testing across repositories gets complicated really fast. To solve these (and many other) problems, some projects will organize their codebases into multi-package repostories (sometimes called [monorepos](https://github.com/babel/babel/blob/master/doc/design/monorepo.md)). Projects like [Babel](https://github.com/babel/babel/tree/master/packages), [React](https://github.com/facebook/react/tree/master/packages), [Angular](https://github.com/angular/angular/tree/master/modules), [Ember](https://github.com/emberjs/ember.js/tree/master/packages), [Meteor](https://github.com/meteor/meteor/tree/devel/packages), [Jest](https://github.com/facebook/jest/tree/master/packages), and many others develop all of their packages within a single repository. **Lerna is a tool that optimizes the workflow around managing multi-package repositories with git and npm.** ### What does a Lerna repo look like? There's actually very little to it. You have a file system that looks like this: ``` my-lerna-repo/ package.json packages/ package-1/ package.json package-2/ package.json ``` ### What can Lerna do? The two primary commands in Lerna are `lerna bootstrap` and `lerna publish`. `bootstrap` will link dependencies in the repo together. `publish` will help publish any updated packages. ## Getting Started > The instructions below are for Lerna 2.x which is currently in beta (actively being worked on). > We recommend using it instead of 1.x for a new Lerna project. Check the [wiki](https://github.com/lerna/lerna/wiki/1.x-Docs) if you need to see the 1.x README. Let's start by installing Lerna globally with [npm](https://www.npmjs.com/). ```sh $ npm install --global lerna # install the latest 2.x version $ npm install --global lerna@2.0.0-beta.13 ``` Next we'll create a new [git](https://git-scm.com/) repository: ```sh $ git init lerna-repo $ cd lerna-repo ``` And now let's turn it into a Lerna repo: ```sh $ lerna init ``` Your repository should now look like this: ``` lerna-repo/ packages/ package.json lerna.json ``` This will create a `lerna.json` configuration file as well as a `packages` folder. ## How it works Lerna allows you to manage your project using one of two modes: Fixed or Independent. ### Fixed/Locked mode (default) Fixed mode Lerna projects operate on a single version line. The version is kept in the `lerna.json` file at the root of your project under the `version` key. When you run `lerna publish`, if a module has been updated since the last time a release was made, it will be updated to the new version you're releasing. This means that you only publish a new version of a package when you need to. This is the mode that [Babel](https://github.com/babel/babel) is currently using. Use this if you want to automatically tie all package versions together. One issue with this approach is that a major change in any package will result in all packages having a new major version. ### Independent mode (`--independent`) Independent mode Lerna projects allows maintainers to increment package versions independently of each other. Each time you publish, you will get a prompt for each package that has changed to specify if it's a patch, minor, major or custom change. Independent mode allows you to more specifically update versions for each package and makes sense for a group of components. Combining this mode with something like [semantic-release](https://github.com/semantic-release/semantic-release) would make it less painful. (There is work on this already at [atlassian/lerna-semantic-release](https://github.com/atlassian/lerna-semantic-release). > The `version` key in `lerna.json` is ignored in independent mode. ## Commands ### init ```sh $ lerna init ``` Create a new Lerna repo or upgrade an existing repo to the current version of Lerna. > Lerna assumes the repo has already been initialized with `git init`. When run, this command will: 1. Add `lerna` as a [`devDependency`](https://docs.npmjs.com/files/package.json#devdependencies) in `package.json` if it doesn't already exist. 2. Create a `lerna.json` config file to store the `version` number. 3. Create a `packages` directory if it hasn't been created already. Example output on a new git repo: ```sh > lerna init $ Lerna v2.0.0-beta.15 $ Creating packages directory. $ Updating package.json. $ Creating lerna.json. $ Successfully created Lerna files ``` #### --independent, -i ```sh $ lerna publish --independent ``` This flag tells Lerna to use independent versioning mode. ### bootstrap ```sh $ lerna bootstrap ``` Bootstrap - or setup - the packages in the current Lerna repo. Installs all of their dependencies and links any cross-dependencies. When run, this command will: 1. Link together all Lerna `packages` that are dependencies of each other. 2. This doesn't currently use [npm link](https://docs.npmjs.com/cli/link) and instead uses a proxy to the actual package in the monorepo. 2. `npm install` all external dependencies of each package. Currently, what Lerna does to link internal dependencies is replace the `node_modules/package-x` with a link to the actual file in the repo. #### How `bootstrap` works Let's use `babel` as an example. - `babel-generator` and `source-map` (among others) are dependencies of `babel-core`. - `babel-core`'s [`package.json`](https://github.com/babel/babel/blob/13c961d29d76ccd38b1fc61333a874072e9a8d6a/packages/babel-core/package.json#L28-L47) lists both these packages as keys in `dependencies`, as shown below. ```js // babel-core package.json { "name": "babel-core", ... "dependencies": { ... "babel-generator": "^6.9.0", ... "source-map": "^0.5.0" } } ``` - Lerna checks if each dependency is also part of the Lerna repo. - In this example, `babel-generator` is a dependency, while `sourcemap` is not. - `sourcemap` is `npm install`ed like normal. - `babel-core/node_modules/babel-generator` is replaced with two files: - A `package.json` with keys `name` and `version` - An `index.js` file with the contents `module.exports = require("relative-path-to-babel-generator-in-the-lerna-repo")` - This links the `babel-generator` package in `node_modules` with the actual `babel-generator` files. ### publish ```sh $ lerna publish ``` Publish packages in the current Lerna project. When run, this command does the following: Creates a new release of the packages that have been updated. Prompts for a new version. Creates a new git commit/tag in the process of publishing to npm. More specifically, this command will: 1. Publish each module in `packages` that has been updated since the last version to npm with the [dist-tag](https://docs.npmjs.com/cli/dist-tag) `lerna-temp`. 1. Run the equivalent of `lerna updated` to determine which packages need to be published. 2. If necessary, increment the `version` key in `lerna.json`. 3. Update the `package.json` of all updated packages to their new versions. 4. Update all dependencies of the updated packages with the new versions. 5. Create a new git commit and tag for the new version. 6. Publish updated packages to npm. 2. Once all packages have been published, remove the `lerna-temp` tags and add the tags to `latest`. > A temporary dist-tag is used at the start to prevent the case where only some of the packages are published; this can cause issues for users installing a package that only has some updated packages. #### --npm-tag [tagname] ```sh $ lerna publish --npm-tag=next ``` When run with this flag, `publish` will publish to npm with the given npm [dist-tag](https://docs.npmjs.com/cli/dist-tag) (defaults to `latest`). This option can be used to publish a [`prerelease`](http://carrot.is/coding/npm_prerelease) or `beta` version. > Note: the `latest` tag is the one that is used when a user runs `npm install my-package`. > To install a different tag, a user can run `npm install my-package@prerelease`. #### --canary, -c ```sh $ lerna publish --canary ``` When run with this flag, `publish` publishes packages in a more granular way (per commit). Before publishing to npm, it creates the new `version` tag by taking the current `version` and appending the current git sha (ex: `1.0.0-alpha.81e3b443`). > The intended use case for this flag is a per commit level release or nightly release. #### --skip-git ```sh $ lerna publish --skip-git ``` When run with this flag, `publish` will publish to npm without running any of the git commands. > Only publish to npm; skip committing, tagging, and pushing git changes (this only affects publish). #### --force-publish [packages] ```sh $ lerna publish --force-publish=package-2,package-4 # force publish all packages $ lerna publish --force-publish=* ``` When run with this flag, `publish` will force publish the specified packages (comma-separated) or all packages using `*`. > This will skip the `lerna updated` check for changed packages and forces a package that didn't have a `git diff` change to be updated. #### --yes ```sh $ lerna publish --canary --yes # skips `Are you sure you want to publish the above changes?` ``` When run with this flag, `publish` will skip all confirmation prompts. Useful in [Continuous integration (CI)](https://en.wikipedia.org/wiki/Continuous_integration) to automatically answer the publish confirmation prompt. #### --repo-version ```sh $ lerna publish --repo-version 1.0.1 # applies version and skips `Select a new version for...` prompt ``` When run with this flag, `publish` will skip the version selection prompt and use the specified version. Useful for bypassing the user input prompt if you already know which version to publish. ### updated ```sh $ lerna updated ``` Check which `packages` have changed since the last release (the last git tag). Lerna determines the last git tag created and runs `git diff --name-only v6.8.1` to get all files changed since that tag. It then returns an array of packages that have an updated file. ### diff ```sh $ lerna diff [package?] $ lerna diff # diff a specific package $ lerna diff package-name ``` Diff all packages or a single package since the last release. > Similar to `lerna updated`. This command runs `git diff`. ### ls ```sh $ lerna ls ``` List all of the public packages in the current Lerna repo. ### run ```sh $ lerna run [script] // runs npm run my-script in all packages that have it $ lerna run test $ lerna run build ``` Run an [npm script](https://docs.npmjs.com/misc/scripts) in each package that contains that script. ## Misc Lerna will log to a `lerna-debug.log` file (same as `npm-debug.log`) when it encounters an error running a command. Lerna also has support for [scoped packages](https://docs.npmjs.com/misc/scope). Running `lerna` without arguments will show all commands/options. ### lerna.json ```js { "lerna": "2.0.0-beta.9", "version": "1.1.3", "publishConfig": { "ignore": [ "ignored-file", "*.md" ] } } ``` - `lerna`: the current version of Lerna being used. - `version`: the current version of the repository. - `publishConfig.ignore`: an array of globs that won't be included in `lerna updated/publish`. Use this to prevent publishing a new version unnecessarily for changes, such as fixing a `README.md` typo. #### --concurrency ```sh $ lerna publish --concurrency 1 ``` How many threads to use when Lerna parallelizes the tasks (defaults to `4`)