Get Started with Nx Release

This recipe guides you through versioning packages, generating changelogs, and publishing packages in a JavaScript monorepo with Nx Release.

Initialize Nx Release in Your Workspace

Install Nx

Ensure that Nx is installed in your monorepo. Check out the Installation docs for instructions on created a new Nx workspace or adding Nx to an existing project.

Add the JavaScript Plugin

The @nx/js package is required for Nx Release to manage and release JavaScript packages. Add it if it is not already installed:

nx add @nx/js

Configure Projects to Release

Nx Release uses Nx's powerful Project Graph to understand your projects and their dependencies.

If you want to release all of the projects in your workspace, such as when dealing with a series of npm library packages, no configuration is required.

If you have a mixed workspace in which you also have some applications, e2e testing projects or other things you don't want to release, you can configure nx release to target only the projects you want to release.

Configure which projects to release by adding the release.projects property to nx.json. The value is an array of strings, and you can use any of the same specifiers that are supported by nx run-many's projects filtering, such as explicit project names, Nx tags, directories and glob patterns, including negation using the ! character.

For example, to release just the projects in the packages directory:

1{ 2 "release": { 3 "projects": ["packages/*"] 4 } 5} 6

Create the First Release

The first time you release with Nx Release in your monorepo, you will need to use the --first-release option. This tells Nx Release not to expect the existence of any git tags, changelog files, or published packages.

Use the --dry-run option

The --dry-run option is useful for testing your configuration without actually creating a release. It is always recommended to run Nx Release once with --dry-run first to ensure everything is configured correctly.

To preview your first release, run:

nx release --first-release --dry-run

Pick a New Version

Nx Release will prompt you to pick a version bump for all the packages in the release. By default, all package versions are kept in sync, so the prompt only needs to be answered one time. If needed, you can configure Nx to release projects independently.

nx release --first-release --dry-run

1 2NX Running release version for project: pkg-1 3 4pkg-1 🔍 Reading data for package "@myorg/pkg-1" from packages/pkg-1/package.json 5pkg-1 📄 Resolved the current version as 0.0.1 from packages/pkg-1/package.json 6? What kind of change is this for the 3 matched projects(s)? … 7❯ major 8 premajor 9 minor 10 preminor 11 patch 12 prepatch 13 prerelease 14 Custom exact version 15

Preview the Results

After this prompt, the command will finish, showing you the preview of changes that would have been made if the --dry-run option was not passed.

nx release --first-release --dry-run

1 2NX Running release version for project: pkg-1 3 4pkg-1 🔍 Reading data for package "@myorg/pkg-1" from packages/pkg-1/package.json 5pkg-1 📄 Resolved the current version as 0.0.1 from packages/pkg-1/package.json 6✔ What kind of change is this for the 3 matched projects(s)? · patch 7pkg-1 ✍️ New version 0.0.2 written to packages/pkg-1/package.json 8 9NX Running release version for project: pkg-2 10 11pkg-2 🔍 Reading data for package "@myorg/pkg-2" from packages/pkg-2/package.json 12pkg-2 📄 Resolved the current version as 0.0.1 from packages/pkg-2/package.json 13pkg-2 ✍️ New version 0.0.2 written to packages/pkg-2/package.json 14pkg-2 ✍️ Applying new version 0.0.2 to 1 package which depends on pkg-2 15 16NX Running release version for project: pkg-3 17 18pkg-3 🔍 Reading data for package "@myorg/pkg-3" from packages/pkg-3/package.json 19pkg-3 📄 Resolved the current version as 0.0.1 from packages/pkg-3/package.json 20pkg-3 ✍️ New version 0.0.2 written to packages/pkg-3/package.json 21 22UPDATE packages/pkg-1/package.json [dry-run] 23 24 "name": "@myorg/pkg-1", 25- "version": "0.0.1", 26+ "version": "0.0.2", 27 "dependencies": { 28 "tslib": "^2.3.0", 29- "@myorg/pkg-2": "0.0.1" 30+ "@myorg/pkg-2": "0.0.2" 31 }, 32 33 UPDATE packages/pkg-2/package.json [dry-run] 34 35 "name": "@myorg/pkg-2", 36- "version": "0.0.1", 37+ "version": "0.0.2", 38 "dependencies": { 39 40 UPDATE packages/pkg-3/package.json [dry-run] 41 42 "name": "@myorg/pkg-3", 43- "version": "0.0.1", 44+ "version": "0.0.2", 45 "dependencies": { 46 47 48NX Updating npm lock file 49 50 51NX Staging changed files with git 52 53 54NOTE: The "dryRun" flag means no changes were made. 55 56NX Previewing an entry in CHANGELOG.md for v0.0.2 57 58 59CREATE CHANGELOG.md [dry-run] 60+ ## 0.0.2 (2024-01-23) 61+ 62+ This was a version bump only, there were no code changes. 63 64NX Staging changed files with git 65 66 67NOTE: The "dryRun" flag means no changelogs were actually created. 68 69NX Committing changes with git 70 71 72NX Tagging commit with git 73 74Skipped publishing packages. 75

Run Without --dry-run

If the preview looks good, run the command again without the --dry-run option to actually create the release.

nx release --first-release

The command will proceed as before, prompting for a version bump and showing a preview of the changes. However, this time, it will prompt you to publish the packages to the remote registry. If you say no, the publishing step will be skipped. If you say yes, the command will publish the packages to the npm registry.

nx release --first-release

1... 2 3✔ Do you want to publish these versions? (y/N) · true 4 5NX Running target nx-release-publish for 3 projects: 6 7- pkg-1 8- pkg-2 9- pkg-3 10 11————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— 12 13> nx run pkg-1:nx-release-publish 14 15 16📦 @myorg/pkg-1@0.0.2 17=== Tarball Contents === 18 19233B README.md 20277B package.json 2153B src/index.ts 2261B src/lib/pkg-1.ts 23=== Tarball Details === 24name: @myorg/pkg-1 25version: 0.0.2 26filename: testorg-pkg-1-0.0.2.tgz 27package size: 531 B 28unpacked size: 624 B 29shasum: {shasum} 30integrity: {integrity} 31total files: 12 32 33Published to https://registry.npmjs.org with tag "latest" 34 35> nx run pkg-2:nx-release-publish 36 37 38📦 @myorg/pkg-2@0.0.2 39=== Tarball Contents === 40 41233B README.md 42277B package.json 4353B src/index.ts 4461B src/lib/pkg-2.ts 45=== Tarball Details === 46name: @myorg/pkg-2 47version: 0.0.2 48filename: testorg-pkg-2-0.0.2.tgz 49package size: 531 B 50unpacked size: 624 B 51shasum: {shasum} 52integrity: {integrity} 53total files: 12 54 55Published to https://registry.npmjs.org with tag "latest" 56 57> nx run pkg-3:nx-release-publish 58 59 60📦 @myorg/pkg-3@0.0.2 61=== Tarball Contents === 62 63233B README.md 64277B package.json 6553B src/index.ts 6661B src/lib/pkg-3.ts 67=== Tarball Details === 68name: @myorg/pkg-3 69version: 0.0.2 70filename: testorg-pkg-3-0.0.2.tgz 71package size: 531 B 72unpacked size: 624 B 73shasum: {shasum} 74integrity: {integrity} 75total files: 12 76 77Published to https://registry.npmjs.org with tag "latest" 78 79————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— 80 81NX Successfully ran target nx-release-publish for 3 projects 82 83

Manage Git Operations

By default, Nx Release will stage all changes it makes with git. This includes updating package.json files, creating changelog files, and updating the package-lock.json file. After staging the changes, Nx Release will commit the changes and create a git tag for the release.

Customize the Commit Message and Tag Pattern

The commit message created by Nx Release defaults to 'chore(release): publish {version}', where {version} will be dynamically interpolated with the relevant value based on your actual release, but can be customized with the release.git.commitMessage property in nx.json.

The structure of the git tag defaults to v{version}. For example, if the version is 1.2.3, the tag will be v1.2.3. This can be customized by setting the release.releaseTagPattern property in nx.json.

For this same example, if you want the commit message to be 'chore(release): 1.2.3' and the tag to be release/1.2.3, you would configure nx.json like this:

1{ 2 "release": { 3 "releaseTagPattern": "release/{version}", 4 "git": { 5 "commitMessage": "chore(release): {version}" 6 } 7 } 8} 9

When using release groups in which the member projects are versioned together, you can also leverage {releaseGroupName} and it will be interpolated appropriately in the commit/tag that gets created for that release group.

Future Releases

After the first release, the --first-release option will no longer be required. Nx Release will expect to find git tags and changelog files for each package. It will also use npm view to look up the current version of packages before publishing, ensuring that the package has not already been published and therefore avoid any conflict errors, meaning you can run the same publish action multiple times without any negative side-effects.

Future releases will also generate entries in CHANGELOG.md based on the changes since the last release. Nx Release will parse the feat and fix type commits according to the Conventional Commits specification and sort them into appropriate sections of the changelog. An example of these changelogs can be seen on the Nx releases page.