Skip to content

chore(deps)!: move @workos-inc/node to peerDependencies#423

Open
Leestex wants to merge 2 commits into
workos:mainfrom
Leestex:fix/peer-dep-workos-node
Open

chore(deps)!: move @workos-inc/node to peerDependencies#423
Leestex wants to merge 2 commits into
workos:mainfrom
Leestex:fix/peer-dep-workos-node

Conversation

@Leestex
Copy link
Copy Markdown

@Leestex Leestex commented May 6, 2026

Closes #422.

Why

@workos-inc/node's types (User, OauthTokens, AuthenticationResponse) are surfaced into authkit-nextjs's public-API interfaces in src/interfaces.ts (Session, UserInfo, HandleAuthSuccessData), but @workos-inc/node is declared in regular dependencies. Any time a consumer's resolved version of @workos-inc/node diverges from the version satisfying the transitive ^9.0.0 range, package managers install a duplicate nested copy under node_modules/@workos-inc/authkit-nextjs/node_modules/@workos-inc/node/. Consumer code that infers return types from withAuth() / refreshSession() then hits TS2883 ("inferred type cannot be named without a reference to 'User' from … This is likely not portable"). Full repro and analysis in #422.

What

Move @workos-inc/node from dependenciespeerDependencies (and add it to devDependencies so the package's own build / typecheck / tests continue to find it). Same pattern as the existing next, react, react-dom peer-dep declarations — the peer-dep contract forces a single resolved copy in the consumer tree by construction.

   "dependencies": {
     "@sindresorhus/fnv1a": "^3.1.0",
-    "@workos-inc/node": "^9.0.0",
     "iron-session": "^8.0.4",
     "jose": "^5.10.0",
     "path-to-regexp": "^6.3.0",
     "valibot": "^1.2.0"
   },
   "peerDependencies": {
+    "@workos-inc/node": "^9.0.0",
     "next": "^13.5.9 || ^14.2.26 || ^15.2.3 || ^16",
     "react": "^18.0 || ^19.0.0",
     "react-dom": "^18.0 || ^19.0.0"
   },
   "devDependencies": {
     ...
+    "@workos-inc/node": "^9.0.0",
     ...
   }

Verification

Locally on this branch:

  • pnpm install — clean install, lockfile regenerates as expected (only the dep-tree @workos-inc/node block moves; no version churn).
  • pnpm run build — green (tsc --project tsconfig.app.json).
  • pnpm run typecheck — green (tsc --project tsconfig.app.json --noEmit && tsc --project tsconfig.test.json --noEmit).
  • pnpm run lint — green (oxlint, 0 warnings / 0 errors).
  • pnpm run test — green (21 test files, 349 tests, 0 failures).

End-to-end: cloning a fresh consumer, removing the resolutions / dedupe workaround, and pointing at this branch via pnpm pack → consumer install resolves a single copy of @workos-inc/node regardless of the consumer's pinned version, and the TS2883 from #422 is gone.

Compatibility / migration

This is a breaking change for any consumer that doesn't already have @workos-inc/node listed in their own dependencies. In practice the realistic impact is small — every authkit-nextjs consumer already calls @workos-inc/node directly for the parts of the WorkOS SDK that authkit-nextjs doesn't wrap (organization management, user management, FGA, audit logs, vault, etc.). The chore(deps)!: prefix on the commit signals the major-bump intent for release-please.

Suggested follow-up release notes (drop into the next major):

@workos-inc/node is now a peer dependency. Consumers must install it directly: pnpm add @workos-inc/node. This prevents TS2883 errors on inferred types from withAuth() and related helpers when the consumer pins a specific version of @workos-inc/node.

If a softer landing is preferred, a backportable variant is to keep @workos-inc/node in both dependencies and peerDependencies — but Yarn / npm / pnpm don't all dedupe that consistently, and the simpler peer-only declaration matches what's already in place for next and react. Happy to adjust if maintainers prefer a different shape.

@workos-inc/node's types (User, OauthTokens, AuthenticationResponse)
are surfaced into authkit-nextjs's public-API interfaces in
src/interfaces.ts (Session, UserInfo, HandleAuthSuccessData). When a
consumer's resolved version of @workos-inc/node differs from the
version satisfying authkit-nextjs's transitive ^9.0.0 range, package
managers install a duplicate copy under
node_modules/@workos-inc/authkit-nextjs/node_modules/@workos-inc/node/.
TypeScript then emits TS2883 on consumer code that infers return types
from withAuth() / refreshSession(), because the canonical path of the
referenced User type crosses a nested node_modules.

Declaring @workos-inc/node as a peer dependency forces a single resolved
copy in the consumer tree by construction — the same pattern already
used here for next, react, and react-dom. Added to devDependencies so
the package's own build, typecheck, and tests continue to find it.

BREAKING CHANGE: consumers must now have @workos-inc/node listed in
their own dependencies. In practice most consumers already do, since
authkit-nextjs only wraps a subset of the WorkOS server SDK and
production code paths typically call WorkOS directly for organization
and user management.
@Leestex Leestex requested a review from a team as a code owner May 6, 2026 16:27
@workos-inc/node is now a peer dependency, so consumers must install it
explicitly alongside @workos-inc/authkit-nextjs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

TS2883: inferred return types from withAuth() / refreshSession() are non-portable when consumer pins a different @workos-inc/node version

1 participant