Skip to content
Latchkey

Node "Named export not found ... CommonJS module" in CI

When ESM imports a CommonJS package, Node can only guarantee the default export. Named imports work only when Node's cjs-module-lexer can detect them statically; otherwise the named export is reported as missing.

What this error means

A named import from a CommonJS package, like import { readFileSync } from "fs-extra", fails with "SyntaxError: Named export 'X' not found. The requested module ... is a CommonJS module".

node
import { mkdirp } from 'fs-extra';
         ^^^^^^
SyntaxError: Named export 'mkdirp' not found. The requested module 'fs-extra' is a
CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export.

Common causes

CommonJS exports the lexer cannot statically detect

The package assigns exports dynamically (computed keys, conditional module.exports), so Node cannot expose them as named ESM imports.

Expecting full named-export interop from CJS

ESM treats CommonJS as a single default export plus whatever the lexer finds; not every property becomes a named export.

How to fix it

Import the default, then destructure

Import the whole CommonJS module as default and pull the members off it at run time.

index.js
import fsExtra from 'fs-extra';
const { mkdirp, readFileSync } = fsExtra;

Use a namespace import

Importing the namespace also works for accessing members the lexer could not pre-bind.

index.js
import * as fsExtra from 'fs-extra';
fsExtra.default.mkdirp('/tmp/x');

How to prevent it

  • Prefer default + destructure when importing CommonJS from ESM.
  • Check whether a package ships a true ESM build with real named exports.
  • Do not assume every CJS property is a named ESM export.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →