Nx 22 expands support beyond the JavaScript ecosystem with first-class support for .NET and Maven! Nx is now your go-to solution for polyglot monorepos. This release also introduces pnpm catalog support, enhances our release workflows, and ships important stability improvements.
We'll be talking about all of these changes and more in our live stream on October 28 at 12pm EDT. Tune in to connect with our Nx engineers and get your questions answered!
Nx 21 brought massive improvements
If you’ve been heads-down lately, you might have missed some significant features that landed during the Nx 21 release cycle. Here’s a quick recap:
- Continuous tasks and Terminal UI: Configure long-running tasks like dev servers to start automatically when needed, with a new interface that keeps all your logs organized
- Angular 20, NestJS 11, and Storybook 9: Major framework updates with automatic migrations
- Enhanced AI integration: The
configure-ai-agentscommand ensures your agents always have what they need, and self-healing CI cuts your Time To Green - Redesigned graph UI: Composite mode by default with better controls and navigation
- Vite 7: Latest tooling support with automatic migration
- Playwright atomized test result merging: Bring together atomized test results in a single artifact
- Dockers deployments made easy -
@nx/docker+nx release= deployment bliss
Now let’s look at what’s new in Nx 22.
Maven support: Fleshing out Java Support

Following our success with the Nx plugin for Gradle, we’re now bringing Maven support to Nx. Using Nx together with Maven provides Nx’s caching and task distribution to your Maven workspaces!
Adding Nx to an existing Maven project adds an nx.json, some nx wrapper binaries, and our Maven Plugin (dev.nx.maven.nx-maven-plugin) to the root pom.xml. The @nx/maven plugin automatically reflects Maven's modules and lifecycle into Nx's project graph. As your Maven modules and goals evolve, Nx will automatically pick them up without maintaining any additional configuration.
1# Install Nx
2brew install nx
3
4# Navigate to a Maven project
5cd /path/to/my-java-service
6
7# Add Maven support
8nx init # Select @nx/maven
9
10# Nx automatically detects your Maven projects
11nx show project my-java-service
12
13# Run mvn install through Nx
14nx install my-java-service
15
16# Run Maven Goals through Nx
17nx spring-boot:run my-java-service
18
19# Run mvn verify for all projects
20nx run-many -t verify
21Like our other plugins, Maven support includes intelligent caching and distributed execution. Your Maven builds will benefit from Nx’s computation caching, which skips unnecessary rebuilds when nothing has changed. For teams using Nx Cloud, this means dramatically faster CI pipelines for your Java projects.
Maven support is experimental for now. This is an initial set of features that users can start to adopt; more features will be coming soon. We will be listening closely for feedback and continue making the Maven support better.
Combined with our existing Gradle support (which saw massive performance improvements in Nx 21), Nx now offers comprehensive support for the Java ecosystem.
Learn more about the Maven plugin
@nx/dotnet: Enterprise-ready .NET development

We’re bringing Nx to the .NET ecosystem! The new @nx/dotnet plugin automatically discovers your .NET projects and infers common targets like build, test, and watch. This means you can start working with your existing .NET solutions immediately without extra configuration.
1# Add the .NET plugin to your workspace
2nx add @nx/dotnet
3
4# Generate a new .NET application
5dotnet new webapi -o ./apps/my-api
6
7# Run common .NET tasks
8nx build my-api
9nx test my-api
10nx watch my-api
11The plugin uses your existing .csproj, .fsproj, or .vbproj files while integrating with Nx’s task graph. This means you get intelligent caching for your .NET builds, distributed task execution on Nx Cloud, and accurate dependency tracking between your .NET projects and any JavaScript projects in your workspace.
This also opens up .NET to all of the CI performance gains offered by Nx Cloud, including remote caching, distributed task execution, flaky task retries, and self-healing CI.
Our @nx/dotnet plugin started life as a community plugin named @nx-dotnet/core, and we recommend all users migrate to @nx/dotnet. This plugin was created by our own Craigory Coppola and reached NPM downloads of over 25k/week. During its life as a community plugin, multiple contributors like Ben Callaghan, Christopher Leigh, and Paulo Oliveira (among others) helped build and support it. Visit the repo and see how a community can come together to build something big.
Explore the .NET plugin documentation
pnpm catalog support: Simplified dependency management
Managing dependencies across a large monorepo can present challenges. Different projects might drift to different versions of the same package, creating inconsistencies and potential bugs. pnpm catalogs solve this by providing a centralized way to define and reference dependency versions.
Nx 22 now supports pnpm catalogs, automatically recognizing and formatting your catalog definitions during migrations. When you run nx migrate, Nx will now properly update versions defined in your catalogs and format the pnpm-workspace.yaml file to keep everything consistent.
1# pnpm-workspace.yaml
2packages:
3 - 'apps/*'
4 - 'libs/*'
5catalog:
6 react: ^19.0.0
7 typescript: ~5.7.0
8 '@nx/react': 22.0.0
9Your projects can then reference these versions using the catalog: protocol:
1{
2 "dependencies": {
3 "react": "catalog:"
4 },
5 "devDependencies": {
6 "typescript": "catalog:",
7 "@nx/react": "catalog:"
8 }
9}
10This makes upgrading dependencies across your entire workspace much simpler. Update the version in one place, and all projects using that catalog entry automatically reference the new version. This pairs perfectly with Nx’s migration system, ensuring your entire monorepo stays in sync.
But this isn’t just for migrations: anything that handles dependencies in package.json files now supports catalogs. That means generators, @nx/eslint rules, module federation utilities, and lockfile pruning all support catalogs in your workspace.
Please note: while plugins maintained by the Nx team have been updated to support catalogs, community plugins that modify package.json files will still need to be updated to support pnpm catalogs. If you’re a plugin author, see the documentation for two helper functions to make this easy: addDependenciesToPackageJson and getDependencyVersionFromPackageJson
Learn more about dependency management with Nx
Enhanced release workflows
We've significantly improved nx release based on feedback from teams using it in production. Several important changes make the release process more intuitive and flexible, progressing us along our journey to fully supporting application releases alongside our powerful existing options for libraries.
Get started with nx release by watching this free video course over at Epic Web!
Graph-aware dependent updates and filtering
Release groups for nx release are a powerful way to configure different parts of your workspace to be released in different ways. This is particularly important when separating our applications from our libraries, which often have very different needs.
Behind the scenes, nx release now constructs a dedicated ReleaseGraph to map out these relationships and allow for filtering (e.g. with --projects/-p or --groups/-g) and updateDependents to be fully aware of even the most complex group configurations.
Related to this, the updateDependents option for versioning has a new possible value: "always". This will inform nx release to update dependency references in dependents wherever they may be, in whatever group, as long as that dependency relationship exists. Combined with the ReleaseGraph aware filtering, using "updateDependents": "always" means that if you had projectA in group1 depending on projectB in group2, and you ran nx release -p projectB or nx release -g group2, you would now update the dependent (projectA) reference on projectB, despite the fact that projectA was outside of the filter.
We feel that this behavior is actually what most people want, most of the time, so in this major release "always" became the default value for updateDependents. The existing options of "auto" and "never" still exist if you wish to go back to the previous behavior or customize it. If you are not leveraging multiple release groups then this change likely does not visibly impact you.
We have also added dedicated guides for:
Cleaner configuration for releaseTag* options
A key aspect of many types of release workflows are git tags, because they inform nx release where to start looking for relevant changes. Over time, the number of options relevant to release tags (what structure/pattern they have, what branches to check, whether semver is required, relationship with docker version etc) has grown and grown.
We therefore felt like the repetition in releaseTagPattern, releaseTagCheckBranchesWhen etc could be better expressed via a releaseTag object with unprefixed nested properties.
For example, in Nx 21 some purely example config might look like:
1{
2 "releaseTagPattern": "{projectName}@{version}",
3 "releaseTagPatternCheckAllBranchesWhen": ["main", "develop"],
4 "releaseTagPatternRequireSemver": false,
5 "releaseTagPatternPreferDockerVersion": "both",
6 "releaseTagPatternStrictPreid": true
7}
8In Nx 22, this same config will automatically be migrated to:
1{
2 "releaseTag": {
3 "pattern": "{projectName}@{version}",
4 "checkAllBranchesWhen": ["main", "develop"],
5 "requireSemver": false,
6 "preferDockerVersion": "both",
7 "strictPreid": true
8 }
9}
10This is much easier to scan and helps keep relevant config grouped together. The previous properties will be supported until Nx 23, with the new ones taking priority.
New programmatic API guide and enhancements for changelogs
We've added a new guide for using the first-class programmatic API for nx release. It can be super useful for creating your own dynamic release scripts while still letting nx release do all the heavy lifting.
When using releaseChangelog function from the programmatic API there is now a replaceExistingContents option which allows you to fully overwrite the existing contents in your configured CHANGELOG.md.
If you are using our ReleaseClient feature, there are two improvements for you to be aware of:
The
ReleaseClientconstructor now allows you to use the provided nx release config as the only source of truth for release configuration, overwriting anything found innx.json. You enable this by setting a second parameter of the constructor totrue(documented in the guide above)You can now provide a reference to a custom changelog renderer directly on custom config that you provide to the
ReleaseClientconstructor instead of having to write it in its own file and provide a path.
All of these features together can be very useful for cases where you are writing very focused changelog generation scripts for only a subset of your workspace, such as one or more applications.
Better conventional commit handling
The way Nx determines relevant conventional commits now matches the behavior of nx affected. This means you now have more control over what changes impact your releases, and are no longer limited to just the changed files within the commits. Things like "implicitDependencies" from nx affected will now work in this context.
Explore the updated Nx Release documentation
AI agent configuration improvements
We’ve made it even easier to configure AI coding assistants to understand your Nx workspace. The configure-ai-agents command now validates your existing AI configuration files, ensuring tools like Cursor, GitHub Copilot, and other AI assistants have everything they need. If one of your agents isn’t up-to-date, you can re-run npx nx configure-ai-agents to update your config. If you’re using Nx Console, it will also check these automatically and suggest updates.
This feature becomes increasingly valuable as your workspace grows and includes projects across multiple technologies. Your AI assistant now understands not only your JavaScript projects, but also your .NET services, Maven applications, and how they all connect.
Learn more about AI integration with Nx
Module Federation updates
For teams using Module Federation, we’ve enhanced support for TypeScript solution-style and package manager workspaces paradigms. This means Module Federation works whether you’re using TypeScript project references, traditional path mappings, and/or package manager workspaces.
This means we can follow best practices when working within TypeScript monorepos when configuring workspace dependencies for our Module Federation projects. We can also ensure Type Safety via standard Node Resolution rather than relying on TS Path Mappings, which can impact build/typecheck performance.
An example of a package.json for a host/consumer application would look like the following:
1{
2 "name": "host",
3 "version": "0.0.1",
4 "private": true,
5 "devDependencies": {
6 "my-remote": "workspace:*",
7 "my-shared-lib": "workspace:*"
8 }
9}
10The corresponding remote application's package.json would contain:
1{
2 "name": "my-remote",
3 "version": "0.0.1",
4 "private": true,
5 "main": "./src/remote-entry.ts",
6 "types": "./src/remote-entry.ts",
7 "exports": {
8 "./Module": "./src/remote-entry.ts"
9 },
10 "devDependencies": {
11 "my-shared-lib": "workspace:*"
12 }
13}
14We’ve also improved support for Angular applications using Rspack with Module Federation, allowing for ESM with Module Federation (previously forced to CJS) which should help keep bundles smaller, and improving live reload support to prevent hot-update loops, making the development experience smoother and faster.
Learn more about Module Federation
Storybook enhancements
The @nx/storybook plugin now automatically infers watch-deps and build-deps targets. This makes it easier to keep your Storybook in sync with your buildable libraries during development. When you’re working on a component library, your Storybook automatically rebuilds when dependencies change.
Breaking Changes
As promised, Nx 22 is focused on stability and cleanup. We’ve removed several previously deprecated features to streamline the codebase and improve maintainability.
Database-backed caching is now standard
The NX_DISABLE_DB environment variable has been removed. All workspaces now use the database-backed caching system introduced in Nx 20. If you were still using the legacy cache, this migration happens automatically.
CreateNodes V1 removed
The older createNodesV1 API for plugin authors has been removed. If you’ve authored custom plugins, ensure they’ve been migrated to createNodesV2. The V2 API provides better performance and more flexibility. For plugin authors be sure to read our compatibility guide to ensure your plugin uses the right API for your use case.
Legacy TypeScript plugin behavior changed
The useLegacyTypescriptPlugin option now defaults to false. This means new workspaces automatically use the more efficient TypeScript handling introduced in Nx 21. Existing workspaces can continue using the legacy behavior if needed, but we recommend migrating to the new approach for better performance.
Webpack and Rspack options cleanup
Several deprecated options have been removed from @nx/webpack and @nx/rspack:
deleteOutputPath: Use the native build tool option insteadsassImplementation: Configure Sass directly in your build tool config
The @nx/rspack:application generator has also been removed in favor of framework-specific options. Use @nx/react:app, @nx/vue:app, or similar generators with the --bundler=rspack flag instead.
Nx Release legacy versioning removed
The deprecated legacy versioning implementation has been completely removed from nx release. If you set release.version.useLegacyVersioning: true in Nx 21, you’ll need to migrate to the new versioning APIs before upgrading to Nx 22.
Inlining feature removed from tsc and swc executors
The experimental and deprecated inlining feature has been removed from the @nx/js:tsc and @nx/js:swc executors. If you were relying on this feature, consider using a bundler like esbuild or webpack instead.
npm legacy peer deps behavior changed
Nx no longer forces --legacy-peer-deps when running npm commands. This aligns with modern npm best practices and ensures your projects resolve dependencies correctly. If you need the legacy behavior, you can configure it in your .npmrc file.
Deprecated simpleName option removed
The simpleName option has been removed from library generators. All libraries now use consistent naming based on your workspace configuration.
Other removals
- The long-deprecated
decorate-cliscript has been removed - Migrations prior to Nx 20 have been removed to reduce package size
- Deprecated Storybook generators have been removed: Use
@nx/storybook:configurationinstead of the old framework-specific generators
Migrating to Nx 22
As always, updating to the latest version of Nx is straightforward:
1nx migrate latest
2This command analyzes your workspace and creates a migration file with all necessary updates. Review the changes, then apply them:
1nx migrate --run-migrations
2For a more visual migration experience, use the Migrate UI in Nx Console, which lets you review and approve each migration individually.
Learn more about the migration process
The nitty gritty
As always, there are many more improvements and fixes we couldn’t cover in detail. See our full release notes on GitHub for all the details.
Keep an eye on our socials and subscribe to our YouTube channel for what’s coming next.
Learn more:





