Skip to content

fix(nextjs): declare dist/esm as ESM via type:module sidecar#8397

Open
jacekradko wants to merge 2 commits intomainfrom
jacek/nextjs-type-module
Open

fix(nextjs): declare dist/esm as ESM via type:module sidecar#8397
jacekradko wants to merge 2 commits intomainfrom
jacek/nextjs-type-module

Conversation

@jacekradko
Copy link
Copy Markdown
Member

Summary

  • Add "type": "module" to packages/nextjs/package.esm.json so dist/esm/package.json declares the bundled ESM output as ESM. Node 22+ and tsx consumers under "type": "module" can now import named exports from @clerk/nextjs/server without the SyntaxError: does not provide an export named 'clerkClient' reported in dist/esm lacks 'type: module' metadata — breaks @clerk/nextjs on Node 22+ under type:module consumers #8396.
  • Swap lint:attw --ignore-rules unexpected-module-syntax for --ignore-rules false-cjs. With type: module set, unexpected-module-syntax stops firing, but attw now flags false-cjs on every subpath because type declarations are still emitted as .d.ts. Splitting types to .d.mts is tracked as a separate follow-up.
  • Add a patch changeset.

Closes #8396

Test plan

  • pnpm --filter @clerk/nextjs build succeeds and dist/esm/package.json contains "type": "module"
  • pnpm --filter @clerk/nextjs lint:attw passes with the swapped ignore rule
  • pnpm --filter @clerk/nextjs lint:publint passes (pre-existing warnings unchanged)
  • pnpm --filter @clerk/nextjs test — no new regressions
  • Reporter's exact repro (tsx + import { clerkClient } from '@clerk/nextjs/server' under "type": "module") now prints clerkClient typeof: function; fails on main with the reported error

Add `"type": "module"` to `package.esm.json` so `dist/esm/package.json`
declares the bundle as ESM. Node 22+ and tsx consumers under
`"type": "module"` can now import named exports from
`@clerk/nextjs/server` without hitting SyntaxError at instantiate time.

Swap `lint:attw --ignore-rules unexpected-module-syntax` (no longer
needed) for `--ignore-rules false-cjs`, which fires because types are
still emitted as `.d.ts`. The `.d.mts` split is tracked separately.

Closes #8396
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 24, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
clerk-js-sandbox Skipped Skipped Apr 24, 2026 1:06am

Request Review

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 24, 2026

🦋 Changeset detected

Latest commit: 05425f5

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@clerk/nextjs Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 24, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 669e67fc-d3b9-4b8c-8d47-69a962bb9093

📥 Commits

Reviewing files that changed from the base of the PR and between 9f0325e and 05425f5.

📒 Files selected for processing (1)
  • packages/nextjs/src/experimental.ts

📝 Walkthrough

Walkthrough

The PR adds a Changesets release note and updates package metadata to mark the ESM build as an ES module by adding "type": "module" to packages/nextjs/package.esm.json. It adjusts packages/nextjs/package.json's lint:attw script to ignore false-cjs instead of unexpected-module-syntax. It also replaces a wildcard re-export in packages/nextjs/src/experimental.ts with explicit named value and type-only exports for several experimental components and hooks.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding type:module to package.esm.json to declare dist/esm as ESM.
Description check ✅ Passed The description comprehensively explains the fix, rationale, and test results related to the ESM declaration issue.
Linked Issues check ✅ Passed All code changes directly address #8396: adding type:module to package.esm.json enables ESM declaration; lint rule swap handles the resulting attw output; explicit re-exports resolve client-boundary issues from ESM declaration.
Out of Scope Changes check ✅ Passed All changes are within scope: package.esm.json modification, lint rule swap, changeset addition, and experimental.ts re-export refactoring all directly support the ESM declaration objective.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 24, 2026

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@8397

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@8397

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@8397

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@8397

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@8397

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@8397

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@8397

@clerk/express

npm i https://pkg.pr.new/@clerk/express@8397

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@8397

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@8397

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@8397

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@8397

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@8397

@clerk/react

npm i https://pkg.pr.new/@clerk/react@8397

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@8397

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@8397

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@8397

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@8397

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@8397

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@8397

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@8397

commit: 05425f5

Webpack's next-flight-loader rejects 'export *' in client boundaries
once a package declares itself as ESM. With the type:module sidecar now
in place, the existing re-export chain through
'@clerk/nextjs/experimental' broke Next.js 15 app builds that imported
from it in client components.

Spell out the named exports to satisfy the client-boundary rule while
keeping the public API intact.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dist/esm lacks 'type: module' metadata — breaks @clerk/nextjs on Node 22+ under type:module consumers

1 participant