Skip to content

Tags: nrwl/nx

Tags

23.1.0-beta.0

Toggle 23.1.0-beta.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
feat(repo): enable the tsgo compiler workspace-wide (#35926)

## Current Behavior

The workspace builds and typechecks every first-party package with
`tsc`. An earlier attempt to enable the Go-based TypeScript compiler
(tsgo) for just `packages/nx` (#35047) was reverted (#35167) because
mixing compilers caused `.tsbuildinfo` version-mismatch cascades — a
downstream `tsc --build` would see a tsgo-stamped build info and
recompile everything.

## Expected Behavior

The entire `@nx/js/typescript` build + typecheck graph — packages,
graph, tools, `e2e/**`, and `nx-dev/ui-fence` — compiles with `tsgo`.
Now that every package is on `nodenext` (NXC-4538), a single compiler
runs across the whole graph, so there is no cross-compiler
`.tsbuildinfo` cascade.

### Changes

- Install `@typescript/native-preview` and set `compiler: "tsgo"` on
**both** `@nx/js/typescript` plugin entries (the package build/typecheck
entry and the e2e/nx-dev typecheck entry — the latter does `tsc --build`
with references into `packages/*`, so it had to move too).
- `tsconfig.base.json`: switch to `nodenext` module resolution, remove
`baseUrl` (tsgo removed it — `TS5102`), and set `strict: false` to
preserve current tsc behavior (tsgo defaults strict on).
- Align spec/e2e tsconfig `module` to `nodenext` (`TS5110`) and add
`customConditions: ["@nx/nx-source"]` to the spec tsconfigs so test
files resolve `@nx/*` subpaths to workspace **source** — notably
`@nx/devkit/internal-testing-utils`, which is excluded from devkit's
build so no declaration is emitted under nodenext.
- Source fixes surfaced by tsgo: two accidental workspace-root
(`baseUrl`-anchored) imports now use package names; `@nx/expo` `addJest`
gets an explicit `Promise<GeneratorCallback>` return type; `@nx/angular`
webpack-browser casts past the angular/webpack plugin type difference;
`graph/client-e2e` cypress global augmentations and `AUTWindow` casts;
`Task` mocks get the required `cache` field;
`update-repos`/`create-embeddings` config fixes.

## Validation

- `build-base`: **42 projects green** under tsgo.
- `typecheck`: **53 projects, 0 errors** under tsgo (entire
`@nx/js/typescript` graph).
- lint / test / e2e: pending CI.

> Note: tsgo's incremental/cached builds occasionally drop emitted
declarations (observed with devkit's `internal-testing-utils`); a
from-scratch build emits them. Worth watching in CI.

The remaining `tsc` users — `astro-docs` (astro check), `nx-dev`'s
Next.js build, and `@nx/angular`'s ng-packagr (ngc) — do **not** `tsc
--build` the packages, so they don't share `.tsbuildinfo` with the tsgo
graph and coexist safely.

## Related Issue(s)

Implements Linear NXC-4539 (builds on NXC-4538 — all packages on
nodenext). No GitHub issue to close.

---------

Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>

23.0.0

Toggle 23.0.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
cleanup(testing): drop sub-default timeout overrides on release e2e s…

…etup hooks (#36009)

## Current Behavior

The `e2e/release` jest project sets a `120000` ms `testTimeout`
(`e2e/release/jest.config.cts`), which Jest applies to any setup hook
without an explicit timeout. Ten release suites instead hardcoded a
`60000` ms timeout on their `newProject`-based `beforeEach`/`beforeAll`
setup, half the suite default. Under CI load that setup (`newProject`
plus `@nx/workspace:npm-package` generators plus git tagging) can run
past 60s, so the hook times out and the suite fails intermittently.
These surface as recurring high-risk flaky tasks on the Nx Cloud
dashboard (version-plans, version-plans-check,
version-plans-only-touched, conventional-commits-config, among others),
and a CI run on this branch reproduced it in the `first-release`
`beforeAll`, where `newProject` alone took 58s.

## Expected Behavior

The setup hooks drop the explicit per-hook timeout and inherit the
suite's `120000` ms default, giving the heavy setup enough headroom and
removing the artificial sub-default cap. The `60000` values were
copy-paste boilerplate carried in by each suite's introducing PR, not a
deliberate limit, and this matches the common e2e idiom where setup
hooks omit a per-hook timeout and rely on the file default.

<!-- polygraph-session-start -->
---
[View session information
↗](https://app.trypolygraph.com/orgs/6a061dcb561c062131116eca/sessions/troubleshoot-flaky-tasks-9deac4de)
<!-- polygraph-session-end -->

23.0.0-rc.4

Toggle 23.0.0-rc.4's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
feat(core): revert array-shape targetDefaults support pending redesig…

…n and reapplication (#36005)

## Current Behavior

`nx.json` `targetDefaults` accepts the new filtered **array shape**
(entries matched by `target`/`executor` and narrowed by
`projects`/`plugin`), alongside the legacy record shape. This was
introduced and refined across:

- #35340 — feat: support filtered array-shape targetDefaults with
projects and source
- #35711 — fix: do not drop target defaults in the 23.0.0 array
migration
- #35752 — docs: document the `convert-target-defaults-to-array`
migration
- #35991 — docs: rewrite the targetDefaults reference and guide for the
array shape

## Expected Behavior

This PR **reverts the array-shape `targetDefaults` feature pending a
redesign**, with the intent that it be **reapplied** once the design is
finalized. `targetDefaults` returns to the record-shape-only form
(`Record<string, Partial<TargetConfiguration>>`).

To keep reapplication easy, the revert is split into focused commits
that mirror the original PRs — the feature can be brought back later by
reverting these reverts.

Changes:

- Restore the `TargetDefaults` type; remove `TargetDefaultEntry`,
`TargetDefaultsRecord`, and `NormalizedTargetDefaults`
- Restore the core target-defaults matcher and project-configuration
utils to the record-shape logic
- Remove the `convert-target-defaults-to-array` migration (and its
registration/docs)
- Remove the devkit `upsertTargetDefault`/`findTargetDefault` helpers
and the `normalize-target-defaults` utility; restore generators across
all plugins (angular, cypress, react, jest, eslint, vite, etc.) to write
the record shape
- Restore the `nx.json` schema `targetDefaults` definition and revert
the array-shape documentation

Unrelated changes that landed in the same files after the feature are
**preserved** (the `CreateNodesV2`→`CreateNodes` rename, the
`findMatchingConfigFiles` optimization, the `nx migrate` config,
`.gitignore` entries, migration-doc packaging globs, and the maven
`createNodesV2` migration).

## Related Issue(s)

Reverts #35340, #35711, #35752, #35991 (to be reapplied after redesign).

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>

23.0.0-rc.3

Toggle 23.0.0-rc.3's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
fix(core): do not fail local plugin lookup when workspace has no root…

… tsconfig (#35969)

## Current Behavior

In a workspace that has **no root `tsconfig.base.json` /
`tsconfig.json`** — packages wired purely through package-manager
workspaces and `package.json` `exports` — every workspace-local plugin
listed in `nx.json` fails to load:

```
 NX   Failed to load 6 Nx plugin(s):

  - @scope/my-plugin: unable to find tsconfig.base.json or tsconfig.json
  ...
```

**This affects the latest stable release, not just the 23 RCs.** The
source-first local plugin resolution was backported to the 22.x line in
**`22.7.3`**. Verified against the published dists of every version in
between:

| nx version | symlinked local plugin, no root tsconfig |
|---|---|
| 22.7.1 | ✅ works |
| 22.7.2 | ✅ works |
| 22.7.3 | ❌ broken (backport of #35631 / #35751 lands) |
| 22.7.4 | ❌ broken |
| 22.7.5 (`latest`) | ❌ broken |
| 23.0.0-rc.0 (`next`) | ❌ broken |
| 22.7.5 + this fix | ✅ works |

Since the source-first local plugin resolution (#35631, #35751),
`resolveNxPlugin` runs `lookupLocalPlugin` for any plugin whose
`require.resolve` lands inside the workspace (true for every symlinked
workspace package). `findNxProjectForImportPath` then calls
`readTsConfigPaths`, which **throws** when no root tsconfig exists —
aborting the whole plugin load before the function ever reaches its
tsconfig-independent fallbacks (package-metadata matching, then Node
resolution of the built artifact).

### Minimal reproduction (5 files, released `nx@22.7.5`)

```jsonc
// package.json
{ "name": "repro", "private": true, "devDependencies": { "nx": "22.7.5" } }
```

```yaml
# pnpm-workspace.yaml
packages:
  - 'packages/*'
```

```jsonc
// nx.json
{ "plugins": ["@repro/my-plugin"] }
```

```jsonc
// packages/my-plugin/package.json
{ "name": "@repro/my-plugin", "exports": { ".": { "default": "./dist/index.js" } } }
```

```js
// packages/my-plugin/dist/index.js
module.exports.createNodesV2 = ['**/never-matches.xyz', async () => []];
```

`pnpm install && pnpm exec nx show projects` →

```
 NX   Failed to load 1 Nx plugin(s):

  - @repro/my-plugin: unable to find tsconfig.base.json or tsconfig.json
```

With this PR's change applied to
`dist/src/project-graph/plugins/resolve-plugin.js` in the same install:
exit 0, projects list as expected.

## Expected Behavior

A missing root tsconfig just means the workspace has no tsconfig path
mappings. `readTsConfigPaths` returns an empty mapping,
`findNxProjectForImportPath` falls through to
`getWorkspacePackagesMetadata` matching, and plugin resolution proceeds
exactly as before the change (source via `exports` conditions when
present, built dist otherwise).

This matches the function's own tolerance for a tsconfig *without*
`compilerOptions.paths` (`return tsconfigPaths ?? {}`).

Given the 22.x backport, a backport of this fix to the 22.x line would
also be appreciated.

## Related Issue(s)

Fixes #35970

Standalone repro (5 files, released `nx@22.7.5`):
https://github.com/agcty/nx-repro-local-plugin-no-root-tsconfig

Regression introduced with the source-first local plugin resolution
(#35631 / #35751), present in `23.0.0-rc.0` and backported into the
stable line in `22.7.3` (22.7.2 and below unaffected). Originally
encountered upgrading a bun-workspaces monorepo (six local inference
plugins, per-package tsconfigs, no root tsconfig) from 22.7.1 to
23.0.0-rc.0 — all `nx` commands fail at plugin load. Additionally
verified end-to-end: in the affected workspace, with this change
applied, all 57 projects and all six local plugins load and tasks run;
the new unit test fails with exactly the pre-fix error when the source
change is reverted.

---------

Co-authored-by: Jason Jean <jason@nrwl.io>

23.0.0-rc.2

Toggle 23.0.0-rc.2's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
chore(gradle): bump gradle project graph plugin version to 0.1.22 (#3…

…5973)

## Current Behavior

Workspaces reference the `dev.nx.gradle.project-graph` Gradle plugin at
version `0.1.21`.

## Expected Behavior

Bump the plugin to `0.1.22`. This release carries the deterministic
project-configuration-hash fix from #35972 (sorting
`options.includeDependsOnTasks` so the `ProjectConfiguration` hash no
longer drifts between JVM runs).

The bump updates the version constant, the plugin's `build.gradle.kts`,
and adds a migration (`change-plugin-version-0-1-22`, gated at
`23.0.0-rc.2`) that updates existing workspaces' version catalogs and
`build.gradle(.kts)` files on `nx migrate`.

> Note: the published `0.1.22` plugin artifact must include #35972
before this is released.

## Related Issue(s)

Follow-up to #35972 (the source fix).

23.0.0-rc.1

Toggle 23.0.0-rc.1's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
fix(core): degrade cooldown-blocked dist-tags within their own channel (

#35967)

## Current Behavior

When a package manager's minimum-release-age (cooldown) policy is
active, `nx migrate` resolves dist-tags through per-package-manager
emulation, and degrading a too-new tag produced inconsistent, often
nonsensical results. `nx migrate next` could resolve to an internal
`pr.*` preview build or a years-old release candidate; the npm path
diverged from what npm itself installs; and yarn errored outright. Each
of npm, pnpm, yarn, and bun carried its own tag-degrade implementation.

## Expected Behavior

Dist-tag degrade is unified into a single rule across all four package
managers. When the resolved tag target is within the cooldown window,
the candidate pool is every version at or below it that is stable, in
the target's own prerelease channel, or on a lower rung of an explicit
channel ladder (`alpha < beta < rc`). That pool is ordered, and the
first compliant version wins:

- Prereleases of the target's exact `major.minor.patch` come first — own
channel, then lower ladder rungs.
- Then everything else, ordered by most recently published.

So `latest` (or any stable tag) lands on the newest compliant stable. A
prerelease tag keeps a compliant prerelease of the release it points at:
every same-line release candidate is exhausted first, and a blocked
`rc.0` with no older rc sibling falls to a same-line `beta.x` rather
than skipping back to the previous stable. A newer-published cross-line
backport can't outrank the same-line beta, and the degrade never climbs
the ladder upward. Channels with no place on the ladder (such as the
internal `pr` builds, or `canary`) stay walled off entirely. `next` is
deliberately left off the ladder: it is pre-rc in some ecosystems
(Angular) but a rolling dev snapshot in others — exactly the class of
build a degrade must never land on. The channel is derived generically
from a version's prerelease identifier, so it works for any package's
naming convention.

## Implementation Details

A shared `degradeTagToCompliant` helper replaces npm's `<=tagTarget`
recursion, pnpm's same-major degrade (and its deprecation tie-break
machinery), yarn's latest-only walk-down, and bun's channel walk. It
builds the pool, orders it (same-line own-channel, then same-line
lower-rung, then by publish date), and returns the first version that
passes the caller's maturity test; each package manager supplies only
that test and its own violation shape. The helper guards against
non-semver dist-tag targets and registry version entries
(`semver.compare` previously threw, and the migrate consumer swallows
unknown errors into a real-install fallback).

The cleanup also drops the now-dead `latestTagDegrade` behavior axis and
the redundant pnpm 10.20 behavior row, along with the tests that pinned
the old version-specific behavior. The npm policy-reader specs are
isolated from the host's real `~/.npmrc` and reuse the real `.npmrc`
parser (`parseNpmrcContent`) instead of a hand-copied mirror, and npm's
tag-path ENOVERSIONS branch is now covered.

<!-- polygraph-session-start -->
---
[View session information
↗](https://app.trypolygraph.com/orgs/6a061dcb561c062131116eca/sessions/fix-nx-migrate-min-release-99acf946)
<!-- polygraph-session-end -->

---------

Co-authored-by: FrozenPandaz <jasonjean1993@gmail.com>

23.0.0-rc.0

Toggle 23.0.0-rc.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
fix(vite): improve vitest 4 migration to better handle vitest workspa…

…ce config (#35940)

## Current Behavior

The `migrate-to-vitest-4` migration defers `vitest.workspace.*` handling
entirely to the AI step, which inlines the project globs verbatim into a
root `vitest.config.*` under `test.projects`. After the upgrade,
packages that run tests through a package.json `vitest` script without a
local config fail with "No projects were found": Vitest 4 discovers the
new root config by walking up from the package directory and resolves
the `test.projects` globs relative to that directory. Workspaces
migrated without the AI step get no workspace-file handling at all.
Reported while testing the Nx 23 betas; reproduction:
https://github.com/juristr/nx23-vitest-issue-repro.

## Expected Behavior

The migration handles workspace files deterministically and produces a
working setup on its own:

- Static `vitest.workspace.*` files (the Nx-generated shape) are inlined
into the root `vitest.config.*` under `test.projects` and deleted. Only
dynamic shapes are forwarded to the AI step.
- Packages that run vitest via a package.json script and have no local
config get a minimal `vitest.config.*` generated, so their tests keep
running from the package directory and `@nx/vitest` infers their test
target.
- When the inlined globs match both a `vite.config.*` and a
`vitest.config.*` in the same directory resolving to the same project
name, the `vite.config.*` file is excluded with a negative glob. This
matches vitest's own vitest-over-vite preference and avoids the "Project
name ... is not unique" startup error that the copied globs previously
produced on root-level runs. Cases that can't be determined statically
are forwarded to the AI step as advisories.

Anything the migration cannot do safely (dynamic workspace files,
configs it can't merge into) is still deferred to the AI step with
accurate context, and the instructions teach the agent the same rules
for the files it inlines itself.

<!-- polygraph-session-start -->
---
[View session information
↗](https://snapshot.app.trypolygraph.com/orgs/69cdc268b6aa527e4129c2b4/sessions/troubleshoot-migrate-to-vitest-4-issue-ba08225a)
<!-- polygraph-session-end -->

---------

Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>

23.0.0-beta.25

Toggle 23.0.0-beta.25's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
chore(repo): finish migrating builds off the workspace-root dist (#35915

)

## Current Behavior

Following the local-dist migration (#35900), several projects were still
writing build or typecheck output to the shared workspace-root `dist/`:

- **Five packages' spec configs** — `@nx/angular-rspack`,
`@nx/angular-rspack-compiler`, `@nx/dotnet`, `@nx/maven`, and `nx` —
kept their `tsconfig.spec.json` `outDir` pointing at
`dist/packages/<name>/spec` even though their lib output had been
migrated to a local `dist`.
- **`tools/workspace-plugin`** built to the shared
`dist/workspace-plugin` (its conformance rules are loaded from the built
output).
- **The graph client** bundled to `dist/apps/graph` and emitted its
typecheck declarations to `dist/graph/client`; the graph libs wrote
spec/storybook typecheck output under `dist/out-tsc`.
- **nx-dev** lib/spec tsconfigs pointed their `outDir` at
`dist/out-tsc/...`.

Separately, astro-docs documentation generation resolved each plugin's
`schema.json` from its **built** `dist` (the migrated
`generators.json`/`executors.json` refs point at `./dist/src/...`).
Reading another project's build output tripped the task sandbox with
undeclared `dist/**/schema.json` reads.

## Expected Behavior

Each project builds to its own local directory, leaving the
workspace-root `dist/` alone:

- The five spec configs now emit to local `dist/spec`.
- `tools/workspace-plugin` builds to `tools/workspace-plugin/dist`; the
seven conformance rule paths in `nx.json` are updated, and
`main`/`typings` are repointed into `dist` so the `@nx/js/typescript`
plugin still infers its build target.
- The graph client bundles to `graph/client/dist` (the `nx` package's
`assets.json` input is updated to match); its typecheck output goes to a
local `out-tsc` so the emitted declarations stay out of the copied
bundle dir. Graph lib spec/storybook output moves to local `dist`.
- nx-dev lib/spec outputs move to local `dist` / `dist/spec`
(preventative — these were vestigial as no target runs `tsc` on most
nx-dev libs today).

astro-docs now reads plugin `schema.json` from source (the verbatim
copy), which also matches `astro-docs:build`'s already-declared
`packages/*/src/.../schema.json` inputs — removing the sandbox violation
without weakening cache correctness.

Validation: `nx build workspace-plugin` + `nx conformance` pass from the
new path; the graph client builds and copies into
`packages/nx/dist/src/core/graph` with no declaration leakage; `nx build
astro-docs` is green (753 pages, no schema-resolution errors); affected
graph and nx-dev `typecheck`/`lint`/`test` pass.

## Related Issue(s)

Follow-up to #35900 (local-dist build migration). No separate issue.

---------

Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>

23.0.0-beta.24

Toggle 23.0.0-beta.24's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
fix(repo): use import type for type-only @nx/devkit imports in copy-a… (

#35897)

…ssets plugin

CreateNodesV2 and TargetConfiguration are types but were imported as
values. The @nx/workspace-plugin package is type: module, so under
Node's native TypeScript stripping (Node >= 22.18) those names are left
as runtime imports. @nx/devkit is CommonJS with no such runtime exports,
so the plugin fails to load -- surfacing on the FreeBSD publish job as
the misleading "imported again after being required. Status = 0" Node
error. Marking them import type lets native strip erase them so the
plugin loads on any Node.

<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #

23.0.0-beta.23

Toggle 23.0.0-beta.23's commit message
docs(module-federation): add Vite Module Federation example page

Add a dedicated docs page under Technologies > Module Federation covering a
Vite-based federation setup using @module-federation/vite, with Nx orchestrating
host/remote tasks. Links the example workspace maintained by Giorgio Boa.

Part of DOC-514.