Nx 23.1 packs a lot into a focused release: support for Angular 22 and TypeScript 6, mouse support in the terminal UI, a more powerful way to define targetDefaults, and more than 90 bug fixes.
Mouse support in the terminal UI
When we shipped the new Nx TUI, it split people in two: those who loved it, and those who missed mouse interactions like scrolling and copying. Well, we fixed that now!
The terminal UI now captures mouse events, which unlocks the interactions people kept asking for:
- Select and copy text straight from a task's output. Drag inside a pane and the selection lands on your clipboard when you release.
- Scroll whatever your mouse is over, without changing which task the app has focused.
- Click a task in the list to select it.
- Click links in the UI, like the Nx Cloud link, to open them.
- Click to dismiss modals and popups.
Mouse interactions are hard to convey in a screenshot, so watch it in action in the release video.
More flexible target defaults
In v23 we introduced the "spread token" giving more flexibility to redefine and inherit target configurations.
This release solves that gap. Until now, a targetDefaults entry was a single object that applied to every target matching the key, which falls apart when two plugins infer a target with the same name (say @nx/vitest and @nx/jest both inferring test) and you want different defaults for each.
That's why starting with v23.1, target defaults can also be an ordered array, where every entry may carry a filter scoping it to a specific plugin, projects, or executor:
{
"targetDefaults": {
"test": [
{ "cache": true },
{
"filter": { "plugin": "@nx/vitest" },
"inputs": ["default", "^production"]
},
{
"filter": { "projects": ["tag:dotnet"] },
"options": { "configuration": "Release" }
}
]
}
}Entries apply in document order and later entries override earlier ones, so an unfiltered entry acts as a catch-all baseline. See the targetDefaults reference for the full shape.
A performance report at the end of every run
To call out potential performance issues with your setup, we now show a short report after every run. It shows in your TUI, in CI, on Nx Agents and in Github actions attached as a job summary.
It currently the report includes:
- Run duration: how long the whole run took.
- Cache hit rate: how much was replayed from cache instead of recomputed.
- Critical path duration: the theoretical minimum the run could have taken, your dependency floor with unlimited parallelism.
- Recoverable time: time you could have gotten back, for example from tasks left waiting on a free execution slot when a slot opens up sooner than the run actually used one.
- Recommendations: targeted, cheapest-action-first suggestions for recovering that time and speeding up future runs.

Apart from surfacing the perf numbers, we also cut overhead in a few places. Task hashing got lighter this cycle too: tasks now share a single fileset hash result instead of each deep-cloning the workspace fileset, cutting memory use and per-task planning overhead on large graphs. A few other paths got faster as well: project graph construction does less redundant work (#36224), the daemon skips recomputing the project graph on no-op file rewrites (#36082), and bun lockfile parsing is quicker (#36198).
TypeScript 6 support
Nx 23.1 plugins ship full support for TypeScript 6. Because a major TypeScript bump can quietly change how your code type-checks, the 23.1 migration can run your typecheck after upgrading and report back, so you find out during the migration rather than in CI.
The post-upgrade typecheck is a prompt-based migration, so it runs when you migrate via the agentic flow. Without an agent, the generator-based changes still apply and Nx lists the skipped prompt steps for you to run yourself. Several other 23.1 migrations work the same way.
We also smoothed over the sharp edges that come with the new default behavior: esModuleInterop is preserved when migrating to TypeScript 6, the pre-6 default of loading all @types packages is restored so ambient types don't silently disappear, and rootDir pinning on composite tsconfigs keeps tsc --build and ts-jest happy. If you're staying on an older TypeScript for now, ts-jest continues to resolve exports-only libraries on versions below 6.
That said, you've probably heard TypeScript 7 is out. You can already use it with Nx today, but run it side-by-side with v6. The main reason is that TypeScript v7 does not yet ship a programmatic API that is used by Nx and many 3rd party tools.

See the TypeScript 7 guide for how to set that up in an Nx workspace.
Angular 22
If you're using Angular with Nx, you'll be happy to hear that Nx 23.1 ships support for Angular 22 and the matching angular-eslint.
A few Angular 22 highlights:
- Signal Forms are now stable, along with
resource()andhttpResource(), capping the signal-first direction Angular has been building toward. - OnPush change detection is the default for new components. Existing components are marked as eager during the migration, so nothing breaks.
- A new
@Servicedecorator, a shorthand for@Injectable({ providedIn: 'root' }). - Async dependency injection via
injectAsync, so heavy services can be lazy-loaded on demand. - Angular Aria is stable, and the release ships notable security hardening.
Have a look at the full Angular v22 announcement for the rest.
This is a breaking change: Angular v19 is no longer supported. nx migrate handles the version bumps and config updates, so the upgrade path runs through the usual migration flow.
ESLint v9 and typescript-eslint v8
Nx 23.1 drops ESLint v8 and moves you to ESLint v9 and bumps to the latest typescript-eslint v8 version.
The corresponding Nx migration adjusts dropped and modified lint rules for you. It also installs angular-eslint automatically when converting Angular projects to flat config, and bumps the React and Cypress ESLint plugins for v9 compatibility.
Framework and bundler updates
A batch of ecosystem support landed this cycle.
- The rspack plugin now supports
@rspack/core@2and@rsbuild/core@2. - The Vite plugin gained configurable
buildTargetandtestTargetoptions onnxViteTsPathsalong with more reliable build coordination in watch and serve, contributed by @shairez (#34890). - Expo support moved up to SDK 56, contributed by @itsjithinv (#35904).
- We also added Next 14-to-15 and React 18-to-19 upgrade paths for the migration flow.
More community fixes landed this cycle too: @aidant made the vitest executor pass mode through to Vitest (#35069), and @SAY-5 turned a confusing failure into an actionable error when pnpm's .modules.yaml is missing (#35666).
And those are just two we called out: 23.1 ships more than 90 bug fixes in total, and quite a few of them come from the community as well. Thank you to everyone who contributed!
Docker read-through cache
ICYMI, Nx Cloud shipped a Docker read-through cache for CI agents. It's a direct response to Docker Hub's failure modes: the strict pull-rate limits shared CI infrastructure burns through fast, and outages like the ~12-hour one on October 20, 2025, which paid Docker plans don't protect you from either. The cache sits between your Nx Agents and Docker Hub: the first pull fetches and caches the image, every pull after that is served locally, no Dockerfile or image reference changes needed.
It's an add-on for orgs on a dedicated compute cluster, turned on from Settings > Add-ons in Nx Cloud, no further config required.
Read the full writeup in "Keep Shipping Through Docker Hub Outages".
How to update Nx
Run the migration and let Nx handle the version bumps and config changes:
npx nx migrate latest
npx nx migrate --run-migrationsThe two breaking changes this release are dropping Angular v19 and ESLint v8. Both are covered by the migrations above, and the TypeScript 6 migration will run your typecheck afterward so you know where you stand before you commit.








