惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

雷峰网
雷峰网
T
Threatpost
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
Tailwind CSS Blog
IT之家
IT之家
H
Hackread – Cybersecurity News, Data Breaches, AI and More
WordPress大学
WordPress大学
博客园 - 司徒正美
Microsoft Azure Blog
Microsoft Azure Blog
Hugging Face - Blog
Hugging Face - Blog
Google DeepMind News
Google DeepMind News
阮一峰的网络日志
阮一峰的网络日志
博客园 - 三生石上(FineUI控件)
Google Online Security Blog
Google Online Security Blog
The GitHub Blog
The GitHub Blog
Martin Fowler
Martin Fowler
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
有赞技术团队
有赞技术团队
S
SegmentFault 最新的问题
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Microsoft Security Blog
Microsoft Security Blog
Jina AI
Jina AI
G
GRAHAM CLULEY
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
Cyber Attacks, Cyber Crime and Cyber Security
A
About on SuperTechFans
Vercel News
Vercel News
The Cloudflare Blog
Cisco Talos Blog
Cisco Talos Blog
小众软件
小众软件
MyScale Blog
MyScale Blog
I
InfoQ
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
人人都是产品经理
人人都是产品经理
The Hacker News
The Hacker News
S
Security Affairs
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
MongoDB | Blog
MongoDB | Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
量子位
酷 壳 – CoolShell
酷 壳 – CoolShell
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
F
Fortinet All Blogs
Latest news
Latest news
Last Week in AI
Last Week in AI
博客园 - 叶小钗
H
Heimdal Security Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
V
Vulnerabilities – Threatpost
Project Zero
Project Zero

Nx Blog

Sharing Tailwind CSS Styles Across Apps in a Monorepo | Nx Blog How SiriusXM Stays Competitive by Iterating and Getting to Market Fast | Nx Blog Agentic Experience Is the New Developer Experience | Nx Blog Nx Joins the Linux Foundation and the Agentic AI Foundation | Nx Blog A Monorepo Is NOT a Monolith | Nx Blog Why we deleted (most of) our MCP tools | Nx Blog Teach Your AI Agent How to Work in a Monorepo | Nx Blog How Broadcom stays efficient and nimble with monorepos | Nx Blog Why Monorepos are King in the Age of AI | Nx Blog Nx 2026 Roadmap: Expanding Agent Autonomy, Improving Performance, Better Polyglot and More | Nx Blog End to End Autonomous AI Agent Workflows with Nx | Nx Blog Autonomous Agents at Scale | Nx Blog Scaling 700+ Projects: How Nx Became a 'No-Brainer' for Caseware | Nx Blog Configure Tailwind v4 with Angular in an Nx Monorepo | Nx Blog The Missing Multiplier for AI Agent Productivity | Nx Blog A Year of Nx Webinars | Nx Blog Wrapping Up 2025 | Nx Blog Nx 22.3 Release: Angular 21 Support, tsgo Compiler, and Prettier v3 | Nx Blog Nx Cloud Release: Agent Resource Usage | Nx Blog Nx Platform Outperforms DIY Cache by 5x | Nx Blog An Nx Carol: Past, Present, and Future of Your Monorepo | Nx Blog Nx 22.1 Release: Terminal UI on Windows, Storybook 10, Vitest 4, and more! | Nx Blog The Compounding Effect: How Nx Features Multiply Performance Gains | Nx Blog 10 Monorepo Myths Debunked: Separating Fact from Fiction | Nx Blog Nx Cloud Release: Enterprise Task Analytics | Nx Blog Watch and Rebuild Storybook Dependencies with Nx | Nx Blog Book - React for Enterprise: Timeless Architecture for Enterprise Apps | Nx Blog Beyond Remote Cache: Unlock 70% More CI Performance | Nx Blog Nx 22 Release: Expanding the build platform | Nx Blog What's the Point of Generating All This Code If You Can't Merge It? | Nx Blog What's New in Nx Self-Healing CI | Nx Blog Nx Highlights: Smarter AI integration, all-new graph UI, and big new versions of your favorite tools | Nx Blog Making the Case for Smarter Monorepos, and How to Not Get Fooled by Myths | Nx Blog Integrating Biome in 20 Minutes | Nx Blog S1ngularity - What Happened, How We Responded, What We Learned | Nx Blog Stop Babysitting Your PRs: Self-Healing CI Cuts Time to Green by 50% | Nx Blog UKG Unifies Their Codebase and Eliminates CI Overhead to Focus on Customer Value | Nx Blog How Git Worktrees Changed My AI Agent Workflow | Nx Blog Nx Cloud Workspace Graph: See Your Organization's Code Structure Like Never Before | Nx Blog Seamless Java Deployment in Nx Using Docker | Nx Blog Getting Mobile Into Your Monorepo: Android + Nx | Nx Blog Polyglot Projects Made Easy: Integrating Spring Boot into an Nx Workspace | Nx Blog The Journey of the Nx Plugin for Gradle: From Prototype to Production | Nx Blog Combining Predictability and Intelligence With Nx Generators and AI | Nx Blog A New UI For The Humble Terminal | Nx Blog Continuous tasks are a huge DX improvement | Nx Blog New and Improved Module Federation Experience with Nx | Nx Blog A New UI for Nx Migration | Nx Blog Custom Task Runners and Self-Hosted Caching Changes | Nx Blog Enterprise Angular Monorepo Patterns | Nx Blog Using Rspack with Angular | Nx Blog Angular Architecture Guide To Building Maintainable Applications at Scale | Nx Blog Modern Angular Testing with Nx | Nx Blog Nx Update: 20.5 | Nx Blog Are Monorepos the Answer to Better AI-Assisted Development? | Nx Blog Making Cursor Smarter with an MCP Server For Nx Monorepos | Nx Blog React Development for 2025 | Nx Blog Using Apollo GraphQL in an Nx Workspace | Nx Blog Angular State Management for 2025 | Nx Blog Tailoring Nx for Your Organization | Nx Blog Nx Cloud Pipelines Come To Nx Console | Nx Blog Define the relationship with monorepos | Nx Blog See your affected project graph in Nx Cloud | Nx Blog Handling CORS In Your Workspace | Nx Blog Improve your architecture and CI pipeline times with Nx projects | Nx Blog Announcing Nx 20 | Nx Blog Introducing Nx Powerpack | Nx Blog Nx 19.5 is here! Stackblitz, Bun, Incremental Builds for Vite, Gradle Test Atomizer | Nx Blog Introducing Explain with AI | Nx Blog Nx Enterprise Podcast Episode 2: Tine Kondo | Nx Blog Monorepos and CI can be a Mess - Here's How Nx and Nx Cloud Fixed It | Nx Blog Nx Enterprise Podcast Episode 1: Hicham El Hammouchi | Nx Blog Nx 19.0 Release!! | Nx Blog Manage Your Gradle Project using Nx | Nx Blog Making the Argument for Monorepos | Nx Blog Reliable CI. A new execution model fixing both flakiness and slowness | Nx Blog Monorepos - Why Speed Matters | Nx Blog Nx Agents Walkthrough: Effortlessly Fast CI Built for Monorepos | Nx Blog Launch Nx Week Recap | Nx Blog Fast, Effortless CI | Nx Blog Introducing @nx/nuxt Enhanced Nuxt.js Support in Nx | Nx Blog What if Nx Plugins Were More Like VSCode Extensions | Nx Blog Monorepos: the Benefits, Challenges, and Importance of Tooling Support | Nx Blog Nx — Highlights of 2023 | Nx Blog Nx 17.2 Update | Nx Blog Unit Testing Expo Apps With Jest | Nx Blog Nx Docs AI Assistant | Nx Blog State Management Nx React Native/Expo Apps with TanStack Query and Redux | Nx Blog Nx 17 has Landed | Nx Blog Nx Conf 2023 — Recap | Nx Blog Nx Raises $16M Series A | Nx Blog Introducing Playwright Support for Nx | Nx Blog Nx 16.8 Release!!! | Nx Blog Step-by-Step Guide to Creating an Expo Monorepo with Nx | Nx Blog Qwikify your Development with Nx | Nx Blog Create Your Own create-react-app CLI | Nx Blog Storybook Interaction Tests in Nx | Nx Blog Evergreen Tooling — More than Just CodeMods | Nx Blog Nx 16.5 Release!!! | Nx Blog A Practical Guide on Effective AI Use - AI as Your Peer Programmer | Nx Blog
Versioning and Releasing Packages in a Monorepo | Nx Blog
Juri Strumpflohner · 2024-02-10 · via Nx Blog

When it comes to publishing NPM packages, there are a bunch of libraries and utilities out there that help with the process. Many of them are tricky when it comes to properly configuring them in a monorepo.

Nx already has all that knowledge, and it can leverage the information it has about your project dependencies and relationships to optimize your task runs.

Here's the structure of our current example workspace we're going to refer to in this article:

@tuskdesign/demo relies on @tuskdesign/forms and @tuskdesign/buttons, and @tuskdesign/forms also depends on @tuskdesign/buttons

As you can see @tuskdesign/forms relies on @tuskdesign/buttons and as such has to consider that when running versioning and publishing.

Note: it is worth mentioning that the Nx community has also stepped up in the past and created jscutlery/semver, a package that adds semantic versioning and publishing to your Nx workspace. Make sure to check that out as well.


📄Free Course: Versioning and Releasing NPM packages with Nx


Table Of Contents

  • Adding Nx
  • Installing the JavaScript/TypeScript versioning Package
  • Running Nx Release
  • Excluding Packages
  • Running the Versioning and Changelog Generation
  • Versioning using Conventional Commits
  • Generating a GitHub Release
  • Programmatic Mode
  • Wrapping Up
  • Learn more

Adding Nx

You can add Nx to your existing monorepo workspace using the following command:

(use npx nx@latest init in a NPM workspace)

This brings up a couple of questions including whether to install Project Crystal plugins.

It gives you some additional benefits (you can read more here), but you don't have to as it is not required for Nx Release.

Installing the JavaScript/TypeScript versioning Package

Nx Release is made to handle the versioning and publishing of any package. For now, the Nx team provides the JS/TS package publishing approach, which comes with the @nx/js. You could provide your own implementation, like for Cargo, NuGet etc.

(We use the -w flag to install it at the monorepo root level)

Running Nx Release

Once you're set-up, you can already go ahead and run the following command:

pnpm nx release --dry-run

This command will do the versioning, changelog generation, and publishing steps together. Note the --dry-run simply simulating a run.

You'll get asked whether you want to release a major, pre-major, minor… release or choose an exact version.

Once this runs through, you might hit the following error:

Error message that reads: "> NX Unable to determine the previous git tag. If this is the first release of your workspace, use the --first-release option or set the "release.changelog.automaticFromRef" config property in nx.json to generate a changelog from the first commit. Otherwise, be sure to configure the "release. releaseTagPattern" property in nx.json to match the structure of your repository's git tags.

Since Nx Release has never been run on this repository, it cannot figure out the historical information, for instance, to generate the changelog starting from previous git tags. Re-run the command with --first-release

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

If you inspect the console output, you can see that:

  • it would increment the version in the package.json
  • update the pnpm (or npm) lockfile
  • stage the changes with git
  • creates a CHANGELOG.md file
  • git commits everything
  • git tags the commit using the version

The dry-run mode also nicely previews all package.json changes in a git diff style:

Note, if you want to get even more insights into what is happening when running the command, you can use the --verbose, which will also print the actual git commands.

Excluding Packages

If you look closely at the dry-run logs, you may notice that Nx Release bumped the version on all of our packages:

  • @tuskdesign/forms
  • @tuskdesign/buttons
  • @tuskdesign/demo

While we want to have it bumped on the forms and buttons packages, the demo is just for us to test things in the workspace. In this particular workspace, Nx Release doesn't have a way to distinguish what is an app and what is a library/package. Note, if you're in an Nx-generated workspace that uses Nx Plugins, you'd potentially have that classification in the project.json files.

In our particular scenario, let's exclude @tuskdesign/demo as follows:

{
    ...
    "release": {
        "projects": ["*", "!@tuskdesign/demo"]
    }
}

You can also explicitly list the packages to be released individually. Or, as shown above, include all (*) and exclude the private package.

If you re-run the nx release command, you'll see that @tuskdesign/demo will be ignored now.

Running the Versioning and Changelog Generation

Once you have configured the excluded packages, feel free to go ahead and run the command without --dry-run:

pnpm nx release --first-release

You can skip the release part when prompted for now. Check how the workspace got updated, incrementing the package.json version property and updating the version on the package dependency definition, i.e. the @tuskdesign/buttons version got updated in the @tuskdesign/forms package.json.

Versioning using Conventional Commits

Instead of manually confirming the next version each time, we can use a versioning strategy: Conventional Commits is a commonly adopted approach for publishing packages.

To configure conventional commits with Nx Release, go to the nx.json and adjust it as follows:

{
    ...
    "release": {
        "projects": ["*", "!@tuskdesign/demo"],
        "version": {
            "conventionalCommits": true
        }
    }
}

If you now run...

pnpm nx release --dry-run

... you'll notice that it doesn't pick up any changes because it leverages conventional commit, and we haven't changed anything yet.

Let's go ahead and change something in our @tuskdesign/buttons package and then commit it as follows:

git commit -am 'feat(buttons): add new background shadow'

Now re-run the nx release command (don't forget the --dry-run). You'll see how it chooses v1.2.0 as our new version (we had v1.1.0 previously), given we added a new feature (denoted by the feat(...) conventional commit).

It also generates a nice CHANGELOG.md for us:

## 1.2.0 (2024-02-09)

### 🚀 Features

- **buttons:** add new background shadow

### ❤️ Thank You

- Juri

## 1.1.0 (2024-02-09)

This was a version bump only, there were no code changes.

Generating a GitHub Release

Instead of just generating a CHANGELOG.md entry in our repository you can also opt-in for creating a Github release (here's the example of the Nx repository).

Use the `createRelease` property and set it to `github`.
{
    ...
    "release": {
        "projects": ["*", "!@tuskdesign/demo"],
        "version": {
            "conventionalCommits": true
        },
        "changelog": {
            "workspaceChangelog": {
                "createRelease": "github"
            }
        }
    }
}

To see the working, you need to make sure to:

  • push the repo to GitHub
  • make some change so you can run the nx release command again and get a changelog generated
  • now also get a GH release created

Note, you can still use --dry-run and it'd show you the URL where the GitHub release would be created. You can also use the --skip-publish to skip the NPM publishing.

Programmatic Mode

As you've seen, you can use nx release right away with minimal configuration. However, we are very well aware that many real-world scenarios are more complex, you want/need more control over when the version is happening, when the changelog generation kicks in and so on. This is why we also introduced a programmatic API.

This approach gives you full control to embed Nx Release into your current release flow. There's a nice example script in our docs that can help you get started.

Create a file — I call it release.ts - at the root of my workspace. Nx Release obviously doesn't care how the file is called or where you place it. You can also go with plain JS.

Here's the example script from our docs:

import { releaseChangelog, releasePublish, releaseVersion } from 'nx/release';
import * as yargs from 'yargs';

(async () => {
  const options = await yargs
    .version(false) // don't use the default meaning of version in yargs
    .option('version', {
      description:
        'Explicit version specifier to use, if overriding conventional commits',
      type: 'string',
    })
    .option('dryRun', {
      alias: 'd',
      description:
        'Whether or not to perform a dry-run of the release process, defaults to true',
      type: 'boolean',
      default: true,
    })
    .option('verbose', {
      description:
        'Whether or not to enable verbose logging, defaults to false',
      type: 'boolean',
      default: false,
    })
    .parseAsync();

  const { workspaceVersion, projectsVersionData } = await releaseVersion({
    specifier: options.version,
    dryRun: options.dryRun,
    verbose: options.verbose,
  });

  await releaseChangelog({
    versionData: projectsVersionData,
    version: workspaceVersion,
    dryRun: options.dryRun,
    verbose: options.verbose,
  });

  // The returned number value from releasePublish will be zero if all projects are published successfully, non-zero if not
  const publishStatus = await releasePublish({
    dryRun: options.dryRun,
    verbose: options.verbose,
  });
  process.exit(publishStatus);
})();

You can invoke it with tsx or tsnode.

Notice by default in the script we have dry-run enabled as a more cautious approach to not accidentally publish something as we keep editing and trying our programmatic setup.

From here on you have full control and can pretty much do whatever works best for your workspace setup. Common examples include:

  • moving files to a common root-level dist/ folder and version and release them from there. This is pretty common to avoid messing with your src files and swapping versions there, allowing you to always depend on the latest local packages for instance.
  • setting up fully automated releases on CI, including enabling provenance support. Our docs have more details on how to set that up or check out the linked talk above which goes through those steps.

Wrapping Up

With this release of Nx Release it is fully ready to be used. Make sure to check out our docs on Managing Releases as well as our release-related recipes.

Here are some example repositories already leveraging Nx release:


Learn more