vercel / vercel/next.js

experimental.swcEnvOptions is not applied to server-side (Node) SWC compilation

Open Beginner friendly
#93,372 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Turbopack
Dominant language
JavaScript
Stars
142k
Forks
32.4k
Avg merge
2d 14h
Merged PRs (30d)
351

Description

Link to the code that reproduces this issue

https://github.com/izemo/izemo-next-app

To Reproduce
  1. Clone the reproduction repo and pnpm install.
  2. The repo is configured with:
    • next: 16.3.0-canary.5
    • engines.node: "22.22.2"
    • .browserslistrc: chrome 110
    • next.config.ts: experimental.swcEnvOptions: { mode: "usage", coreJs: "3.49" }
  3. app/server/page.tsx is a Server Component (with export const dynamic = "force-dynamic") that calls RegExp.escape("a.b.c"). RegExp.escape is TC39 Stage 4 (ES2025) and is missing in both Chrome 110 and Node 22.22.2; it landed in Chrome 136 / Node 24.
  4. app/client/page.tsx is the client-side mirror (call inside useEffect).
  5. Run pnpm build --webpack and pnpm start.
  6. curl -i http://localhost:3000/server.
Current vs. Expected behavior

Expected: With experimental.swcEnvOptions: { mode: "usage", coreJs: "3.49" },
SWC's preset-env should auto-inject the core-js polyfill for RegExp.escape
into BOTH the client bundle and the Node-side server bundle, since neither
browserslist target (chrome 110) nor engines.node (22.22.2) ships it natively.

Actual: The polyfill is injected only into the client bundle; the
server bundle emits the call as-is.

Evidence after pnpm build --webpack:

Client bundle (.next/static/chunks/app/client/page-*.js):
- escape:function polyfill body → 1 occurrence (core-js inlined) ✅

Server bundle (.next/server/app/server/page.js):
- escape:function polyfill body → 0 occurrences ❌
- Verbatim user code in bundle : RegExp.escape("a.b.c")

Hitting the route on Node 22.22.2 fails:

$ curl -i http://localhost:3000/server
HTTP/1.1 500 Internal Server Error
...
⨯ TypeError: RegExp.escape is not a function
at f (.next/server/app/server/page.js:2:13549)
at stringify () {
digest: '891653235'
}

Root cause (verified by reading the installed source):
In packages/next/src/build/swc/options.ts (webpack path), the isServer
branch hardcodes env: { targets: { node: process.versions.node } } and
never spreads swcEnvOptions, while the client branch correctly does
env: { targets: supportedBrowsers, ...swcEnvOptions }.

Provide environment information
Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.2.0
Binaries:
  Node: 22.22.2
  npm: 10.9.7
  pnpm: 10.33.2
Relevant Packages:
  next: 16.3.0-canary.5
  react: 19.2.4
  react-dom: 19.2.4
  typescript: 5.9.3
Next.js Config:
  output: N/A
Which area(s) are affected? (Select all that apply)

Turbopack

Which stage(s) are affected? (Select all that apply)

next build (local), next start (local)

Additional context

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with packages/next/src/build/swc/options.ts and inspect the isServer branch alongside the client branch that applies swcEnvOptions. Reproduce the failure from izemo/izemo-next-app with pnpm build --webpack, then verify that the server bundle includes the core-js polyfill and the /server route works under Node 22.22.2.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, next.js
Domain
backend, build-system
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.