Skip to content

@next/eslint-plugin-next incorrect named exports #86504

@thernstig

Description

@thernstig

Link to the code that reproduces this issue

https://github.com/thernstig/eslint-mcp-jiti

To Reproduce

  1. Install the packages
  2. Execute this in a terminal: node -e "import {configs} from '@next/eslint-plugin-next';"

Current vs. Expected behavior

Expected

It should return with no errors.

Actual

> node -e "import {configs} from '@next/eslint-plugin-next';"
file:///home/tobias/code/repro-eslint-mcp-jiti/[eval1]:1
import {configs} from '@next/eslint-plugin-next';
        ^^^^^^^
SyntaxError: Named export 'configs' not found. The requested module '@next/eslint-plugin-next' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from '@next/eslint-plugin-next';
const {configs} = pkg;

    at #_instantiate (node:internal/modules/esm/module_job:254:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:369:5)
    at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:278:26)
    at async ModuleLoader.executeModuleJob (node:internal/modules/esm/loader:275:20)
    at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:101:5)

Node.js v24.11.0

Provide environment information

Operating System:
  Platform: linux
  Arch: x64
  Version: #1 SMP Tue Nov 5 00:21:55 UTC 2024
  Available memory (MB): 31662
  Available CPU cores: 32
Binaries:
  Node: 24.11.0
  npm: 11.6.1
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  next: 16.0.4 // Latest available version is detected (16.0.4).
  eslint-config-next: N/A
  react: 19.2.0
  react-dom: 19.2.0
  typescript: N/A
Next.js Config:
  output: N/A

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

Linting

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

Other (Deployed)

Additional context

I do not know what the fault is, but I compared how @next/eslint-plugin-next sets its named exports compared to typescript-eslint, which also sets named exports (both being in Common JS (CJS)). An AI summarized it as below. Again, might be wrong, but adding for context:

@next/eslint-plugin-next defines top-level getters on exports
Object.defineProperty(exports, "configs", { enumerable: true, get: () => configs });
Node ignores top-level getters for synthetic named exports when importing CJS as ESM.

typescript-eslint works because it assigns a data property at the top level:
exports.configs = createConfigsGetters({ ... }); // data property
Node sees a top-level data property → creates a synthetic named export → import { configs } works.

To fix @next/eslint-plugin-next do this:

// Instead of top-level getter:
Object.defineProperty(exports, "configs", {
 enumerable: true,
 value: configs  // <- data property, not a getter
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    LintingRelated to `next lint` or ESLint with Next.js.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions