nextjs - 💡(How to fix) Fix ERR_REQUIRE_ESM regression in 16.2.0 for apps with "type": "module" deployed to Vercel [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
vercel/next.js#91740Fetched 2026-04-08 01:07:06
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
0
Timeline (top)
closed ×1commented ×1labeled ×1locked ×1

Error Message

Error running the exported Web Handler: Error: require() of ES Module /var/task/apps/web/.next/server/middleware.js from /var/task/apps/web/___next_launcher.cjs not supported. middleware.js is treated as an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which declares all .js files in that package scope as ES modules.

at <unknown> (../../../../opt/rust/nodejs.js:2:13531)
at Module.pn (../../../../opt/rust/nodejs.js:2:13909)
at Xe.e.<computed>.Ye._load (../../../../opt/rust/nodejs.js:2:13501) {

code: 'ERR_REQUIRE_ESM' }

Root Cause

We discovered this today (March 20, 2026). This appears to be a regression of the fix for #86434, which was closed Feb 24, 2026 after a Vercel build-side fix.

What we've confirmed locally:

  1. Next.js correctly generates .next/package.json with {"type": "commonjs"} during build — verified in both 16.1.7 and 16.2.0
  2. All server output (middleware.js, page.js) is correctly emitted as CJS — files use require() and module.exports
  3. The issue is at the Vercel runtime level___next_launcher.cjs calls require('.next/server/middleware.js'), but Node.js resolves the file type by walking up to the app's package.json ("type": "module") instead of finding the .next/package.json override

Why 16.1.7 works but 16.2.0 doesn't:

The Vercel-side fix for #86434 was built against the 16.1.x output format. Next.js 16.2.0 changed the deploy adapter outputs and handler interfaces (#88247 — adapterPath promoted to stable). The Vercel builder (@vercel/next) likely uses a different code path for 16.2.0 that doesn't include .next/package.json in the Lambda function bundle.

NODE_OPTIONS workaround doesn't work:

The Vercel docs suggest setting NODE_OPTIONS=--experimental-require-module to re-enable require(ESM). However, community reports indicate Vercel's runtime injects --no-experimental-require-module into process.execArgv, which overrides the env var.

Fix Action

Fix / Workaround

NODE_OPTIONS workaround doesn't work:

Our workaround

Code Example

Error running the exported Web Handler: Error: require() of ES Module /var/task/apps/web/.next/server/middleware.js from /var/task/apps/web/___next_launcher.cjs not supported.
middleware.js is treated as an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which declares all .js files in that package scope as ES modules.

    at <unknown> (../../../../opt/rust/nodejs.js:2:13531)
    at Module.pn (../../../../opt/rust/nodejs.js:2:13909)
    at Xe.e.<computed>.Ye._load (../../../../opt/rust/nodejs.js:2:13501) {
  code: 'ERR_REQUIRE_ESM'
}

---

Error: require() of ES Module /var/task/apps/web/.next/server/app/_not-found/page.js from /var/task/apps/web/___next_launcher.cjs not supported.

---

Operating System: Linux (Vercel serverless)
Node.js: 24.x (Vercel runtime)
Next.js: 16.2.0
Package Manager: pnpm 10.30.x
Deployment: Vercel (serverless functions)
RAW_BUFFERClick to expand / collapse

Link to the code that reproduces this issue

Minimal reproduction steps below

To Reproduce

  1. Create a Next.js 16 app in a pnpm monorepo
  2. Set "type": "module" in the app's package.json
  3. Add a proxy.ts (or middleware.ts) with basic request handling
  4. Deploy to Vercel with [email protected]
  5. Any request fails at runtime with ERR_REQUIRE_ESM

Current vs. Expected behavior

Current (16.2.0): All routes fail at runtime:

Error running the exported Web Handler: Error: require() of ES Module /var/task/apps/web/.next/server/middleware.js from /var/task/apps/web/___next_launcher.cjs not supported.
middleware.js is treated as an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which declares all .js files in that package scope as ES modules.

    at <unknown> (../../../../opt/rust/nodejs.js:2:13531)
    at Module.pn (../../../../opt/rust/nodejs.js:2:13909)
    at Xe.e.<computed>.Ye._load (../../../../opt/rust/nodejs.js:2:13501) {
  code: 'ERR_REQUIRE_ESM'
}

The same error also occurs for page routes:

Error: require() of ES Module /var/task/apps/web/.next/server/app/_not-found/page.js from /var/task/apps/web/___next_launcher.cjs not supported.

Expected: The app deploys and runs correctly, as it does on [email protected].

Provide environment information

Operating System: Linux (Vercel serverless)
Node.js: 24.x (Vercel runtime)
Next.js: 16.2.0
Package Manager: pnpm 10.30.x
Deployment: Vercel (serverless functions)

Which area(s) are affected?

Middleware, Deployment, Proxy

Analysis

We discovered this today (March 20, 2026). This appears to be a regression of the fix for #86434, which was closed Feb 24, 2026 after a Vercel build-side fix.

What we've confirmed locally:

  1. Next.js correctly generates .next/package.json with {"type": "commonjs"} during build — verified in both 16.1.7 and 16.2.0
  2. All server output (middleware.js, page.js) is correctly emitted as CJS — files use require() and module.exports
  3. The issue is at the Vercel runtime level___next_launcher.cjs calls require('.next/server/middleware.js'), but Node.js resolves the file type by walking up to the app's package.json ("type": "module") instead of finding the .next/package.json override

Why 16.1.7 works but 16.2.0 doesn't:

The Vercel-side fix for #86434 was built against the 16.1.x output format. Next.js 16.2.0 changed the deploy adapter outputs and handler interfaces (#88247 — adapterPath promoted to stable). The Vercel builder (@vercel/next) likely uses a different code path for 16.2.0 that doesn't include .next/package.json in the Lambda function bundle.

NODE_OPTIONS workaround doesn't work:

The Vercel docs suggest setting NODE_OPTIONS=--experimental-require-module to re-enable require(ESM). However, community reports indicate Vercel's runtime injects --no-experimental-require-module into process.execArgv, which overrides the env var.

Our workaround

Pinning next to 16.1.7 across the workspace (including a pnpm.overrides entry to force all transitive peer deps). This restores working deployments but blocks upgrading to 16.2.0+.

Related

  • #86434 — Original issue (closed/locked, reportedly fixed on Vercel build side)
  • #88247 — 16.2.0 adapter changes (likely regression source)
  • #62521 — ESM build with standalone output issues

extent analysis

Fix Plan

To resolve the ERR_REQUIRE_ESM issue, we need to ensure that the middleware.js and page.js files are treated as CommonJS modules instead of ES modules.

Here are the steps to fix the issue:

  • Update the next.config.js file to include the following configuration:
module.exports = {
  //... other configurations ...
  experimental: {
    externalDir: true,
  },
}
  • Create a new file named next.package.json in the root of your project with the following content:
{
  "type": "commonjs"
}

However, since the issue is at the Vercel runtime level, we need to override the package.json type for the .next directory.

One possible solution is to use a custom vercel-build script to modify the package.json file in the .next directory.

Here's an example of how you can achieve this:

// vercel-build.js
const fs = require('fs');
const path = require('path');

const nextPackageJsonPath = path.join(__dirname, '.next', 'package.json');

fs.readFile(nextPackageJsonPath, 'utf8', (err, data) => {
  if (err) {
    console.error(err);
    return;
  }

  const packageJson = JSON.parse(data);
  packageJson.type = 'commonjs';

  fs.writeFile(nextPackageJsonPath, JSON.stringify(packageJson, null, 2), (err) => {
    if (err) {
      console.error(err);
    }
  });
});

Then, in your vercel.json file, add the following script:

{
  "version": 2,
  "builds": [
    {
      "src": "vercel-build.js",
      "use": "@vercel/static-build"
    }
  ]
}

This script will modify the package.json file in the .next directory to set the type to commonjs, which should resolve the ERR_REQUIRE_ESM issue.

Verification

To verify that the fix worked, deploy your application to Vercel and check the logs for any errors. If the issue is resolved, you should no longer see the ERR_REQUIRE_ESM error.

Extra Tips

  • Make sure to test your application thoroughly after applying the fix to ensure that it works as expected.
  • If you're using a pnpm workspace, make sure to update the pnpm version to the latest version to ensure that you have the latest fixes and features.
  • Consider opening an issue with Vercel to report the problem and ask for a more permanent solution.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

nextjs - 💡(How to fix) Fix ERR_REQUIRE_ESM regression in 16.2.0 for apps with "type": "module" deployed to Vercel [1 comments, 2 participants]