jestjs/jest · error · Error
Package '${pkg.name}' declares '@jest/test-utils' as depende
Error message
Package '${pkg.name}' declares '@jest/test-utils' as dependency, but it must be declared as dev dependency What it means
scripts/buildTs.mjs lints each monorepo package: @jest/test-utils is a test-only helper and must never ship as a runtime dependency. At buildTs.mjs:99-109 it checks pkg.dependencies for '@jest/test-utils'; if present (and it should never be), it throws. This keeps test utilities out of the published dependency graph.
Source
Thrown at scripts/buildTs.mjs:104
const references = tsConfig.references.map(({path}) => path);
assert.deepStrictEqual(
references,
jestDependenciesOfPackage,
`Expected declared references to match dependencies in package ${
pkg.name
}. Got:\n\n${references.join(
'\n',
)}\nExpected:\n\n${jestDependenciesOfPackage.join('\n')}`,
);
}
let hasJestTestUtils = Object.keys(pkg.dependencies || {}).includes(
'@jest/test-utils',
);
if (hasJestTestUtils) {
throw new Error(
chalk.red(
`Package '${pkg.name}' declares '@jest/test-utils' as dependency, but it must be declared as dev dependency`,
),
);
}
hasJestTestUtils = Object.keys(pkg.devDependencies || {}).includes(
'@jest/test-utils',
);
const tsConfigPaths = glob.sync('**/__tests__/tsconfig.json', {
absolute: true,
cwd: packageDir,
});
const testUtilsReferences = tsConfigPaths.filter(tsConfigPath => {
const tsConfig = JSON.parse(
stripJsonComments(fs.readFileSync(tsConfigPath, 'utf8')),View on GitHub (pinned to f49721c78e)
Solutions
- Move "@jest/test-utils": "..." from `dependencies` to `devDependencies` in the offending package's package.json.
- Re-run scripts/buildTs.mjs to confirm the lint passes.
- Audit CI to reject @jest/test-utils in the dependencies block going forward.
Example fix
// before (package.json)
"dependencies": { "@jest/test-utils": "workspace:*" }
// after
"devDependencies": { "@jest/test-utils": "workspace:*" } Defensive patterns
Strategy: validation
Validate before calling
function assertTestUtilsNotInDeps(pkg) {
const deps = Object.keys(pkg.dependencies || {});
if (deps.includes('@jest/test-utils')) {
throw new Error(`${pkg.name}: move @jest/test-utils to devDependencies`);
}
} Type guard
function isTestUtilsOnlyDevDep(pkg): boolean {
return !Object.keys(pkg.dependencies || {}).includes('@jest/test-utils');
} Prevention
- Always place @jest/test-utils under devDependencies, never dependencies.
- Add a package.json lint rule (or CI check) that rejects @jest/test-utils in the dependencies block.
- When scaffolding new packages, start from a template that puts test-only helpers in devDependencies.
When it happens
Trigger: Running the TS build/validate script after someone added "@jest/test-utils" under `dependencies` (instead of `devDependencies`) in a package's package.json.
Common situations: Auto-generating a package.json that merged all requires into dependencies; copy-pasting a dependency entry into the wrong block; tooling that doesn't distinguish dep vs devDep.
Related errors
- Package '${pkg.name}' does not declare '@jest/test-utils' as
- Package '${pkg.name}' declares '@jest/test-utils' as dev dep
- Binary in package "${pkg.name}" with name "${binName}" at ${
- No exports found in package ${pkg.name}
- ${file} has the following non-node type references: ${refer
AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03).
Data as JSON: /data/errors/be95985854b098e1.json.
Report an issue: GitHub.