feat(ts#react-website): override the express @nx/react resolves to, and take nx 23.1.2 - #1148
Merged
Merged
Conversation
…nd take nx 23.1.2 @nx/react 23.1.2 adds an optional `express: ^4.21.2` peer for its module-federation dev-server, a major behind the express generated projects use (`@strands-agents/sdk` peers on `^5.1.0`). npm alone fails the whole install on an optional peer it cannot satisfy: npm error ERESOLVE could not resolve npm error peerOptional express@"^4.21.2" from @nx/react@23.1.2 npm error Conflicting peer dependency: express@5.2.1 pnpm, bun, yarn 4 and yarn classic all install and only warn, which is why holding nx back was the way to land the last dependency update. Nothing in a generated workspace loads express through @nx/react — the peer only has to be satisfiable — so pin it to the version already vended via npm's `overrides`, scoped to `@nx/react` so every other consumer of express keeps its own resolution and no second copy is installed. This follows terraform#project, which resolves the same class of upstream peer conflict the same way. `express` is declared `versionOnly`, so the version sync owns it: the pin is reachable only through the override, and a stale one would leave npm unable to resolve once the vended express moves on. A migration adds the override to workspaces that already have a website, which would otherwise be unable to install once their nx moves onto 23.1.2. It is npm-only, skips a workspace with no website, keeps a version the user pinned deliberately, and reports the string-form `overrides['@nx/react']` case it cannot safely nest under.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1148 +/- ##
==========================================
+ Coverage 88.51% 88.59% +0.08%
==========================================
Files 245 246 +1
Lines 10464 10485 +21
Branches 2476 2482 +6
==========================================
+ Hits 9262 9289 +27
+ Misses 524 521 -3
+ Partials 678 675 -3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
cogwirrel
approved these changes
Aug 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reason for this change
The nx 23.1.2 bump was held back in #1145 because it broke
Smoke Tests - npm.@nx/react23.1.2 adds an optionalexpresspeer that 23.1.1 did not declare:It is for the module-federation dev-server, and it is
optional(peerDependenciesMeta.express.optional: true) — nothing in a generated workspace loads express through@nx/react. But generated projects pin express 5.2.1, the major@strands-agents/sdkpeers on (express: ^5.1.0), and npm fails the whole install on an optional peer it cannot satisfy:I checked all five package managers against the conflict directly: only npm fails. pnpm, bun, yarn 4 and yarn classic install and emit a warning. Since 23.1.2 is the latest nx release, holding back was the only option at the time — this unblocks it.
Description of changes
Vend a scoped npm override.
ts#react-websitepins the express@nx/reactresolves to, via npm'soverrides:Scoped to
@nx/reactrather than pinning express workspace-wide: the peer only has to be satisfiable, so this keeps npm's check honest for every other consumer of express and installs no second copy (verified in the lockfile — onenode_modules/express, at 5.2.1).This follows the existing precedent in
terraform#project, which resolves the same class of upstream peer conflict the same way (@nx-extend/terraform's@nx/devkitpeer), including declaring the dependencyversionOnlypurely to feed the override.expressis declaredversionOnly, so the version sync owns it. The pin is reachable only through the override, so without this a stale override would silently rot and break npm resolution once the vended express moves on. There's a test asserting the sync carries it forward.Take nx 23.1.2 across
versions.ts, bothpackage.jsons, and register thenx-23.1.2-nx-packagespackageJsonUpdatesentry.A migration adds the override to existing workspaces, which would otherwise be unable to install once their nx moves onto 23.1.2. It is npm-only, skips a workspace with no website, keeps a version the user pinned deliberately, and reports (rather than clobbers) the string-form
overrides['@nx/react']case it cannot safely nest under.Description of how you validated changes
@nx/react23.1.2 + express 5.2.1 +@strands-agents/sdk):ERESOLVEwithout the override,up to datewith it, and a lockfile carrying exactly one express at 5.2.1. This is the check that matters — the failure was npm's resolver, not anything a unit test sees.pnpm nx test nx-plugin— 3940 tests pass across 218 files. New tests: the override is written on npm; it is not written on pnpm/yarn/bun; the version sync carries it forward; plus 9 migration tests (applies, preserves sibling keys and other overrides, skips non-npm, skips a workspace with no website, keeps a user's pin, reports the string form, idempotent).pnpm lintandpnpm nx syncpass;LICENSE-THIRD-PARTYregenerated.Note the smoke tests are the real gate here, since they run actual installs across every package manager — worth watching on this PR specifically.
Issue # (if applicable)
N/A — follows on from #1145, which held the bump back.
Checklist
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license