jestjs/jest · error · Error
No exports found in package ${pkg.name}
Error message
No exports found in package ${pkg.name} What it means
scripts/build.mjs generates an ESM (.mjs) re-export wrapper by requiring the package's CJS entry point (pkg.main) and enumerating its named/default exports. At build.mjs:78-79, if Object.keys(cjsModule) contains nothing other than __esModule/default, the package is considered to export nothing and the build aborts. This catches packages whose entry file has no real public surface before shipping a broken .mjs.
Source
Thrown at scripts/build.mjs:79
`Main file "${pkg.main}" in "${pkg.name}" should exist`,
);
if (typeOnlyPackages.has(pkg.name)) {
continue;
}
// TODO: can we get exports from a file from webpack's `stats`?
const cjsModule = require(entryPointFile);
const exportStatements = Object.keys(cjsModule)
.filter(name => name !== '__esModule' && name !== 'default')
.map(name => `export const ${name} = cjsModule.${name};`);
if (cjsModule.default) {
exportStatements.push('export default cjsModule.default;');
}
if (exportStatements.length === 0) {
throw new Error(`No exports found in package ${pkg.name}`);
}
const mjsEntryFile = entryPointFile.replace(/\.js$/, '.mjs');
const esSource = dedent`
import cjsModule from './index.js';
${exportStatements.join('\n')}
`;
await fs.promises.writeFile(mjsEntryFile, `${esSource}\n`);
}
process.stdout.write(`${OK}\n`);
}
try {
await buildNodePackages();View on GitHub (pinned to f49721c78e)
Solutions
- Add at least one named or default export to the package's main entry file (the file referenced by pkg.main).
- Confirm pkg.main points at the intended entry file and that file was built (the script first asserts fs.existsSync(entryPointFile)).
- Re-run the build after fixing exports; the require() at build.mjs:69 must observe real keys.
Example fix
// before (packages/foo/build/index.js)
function internal() {}
module.exports = {};
// after
function foo() { return 'foo'; }
module.exports = { foo }; Defensive patterns
Strategy: validation
Validate before calling
function assertPackageHasExports(entryFile, pkgName) {
const mod = require(entryFile);
const names = Object.keys(mod).filter(k => k !== '__esModule' && k !== 'default');
if (names.length === 0 && !mod.default) {
throw new Error(`No exports found in package ${pkgName}`);
}
} Type guard
function packageHasExports(entryFile) {
const mod = require(entryFile);
const named = Object.keys(mod).filter(k => k !== '__esModule' && k !== 'default');
return named.length > 0 || !!mod.default;
} Prevention
- Ensure every package's main entry file exports at least one named or default binding.
- Verify pkg.main points at the correct built file before running the monorepo build.
- Add a smoke test that requires each package entry and asserts it has a non-empty export surface.
When it happens
Trigger: Running the monorepo build (`node scripts/build.mjs` / the build script) for a package whose index.js has no exports — e.g. a barrel file that forgot to re-export, a file with only internal helper declarations, or one where exports are guarded behind a condition that evaluates false at require time.
Common situations: Adding a new package but not yet exporting anything from its entry point; refactoring that moves exports into a sub-module without re-exporting from index.js; side-effectful entry files that assign to a conditional that is falsy during build.
Related errors
- Package '${pkg.name}' declares '@jest/test-utils' as depende
- Package '${pkg.name}' declares '@jest/test-utils' as dev dep
- Package '${pkg.name}' does not declare '@jest/test-utils' as
- ${file} has the following non-node type references: ${refer
- Binary in package "${pkg.name}" with name "${binName}" at ${
AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03).
Data as JSON: /data/errors/d43186dfd73421aa.json.
Report an issue: GitHub.