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

  1. Move "@jest/test-utils": "..." from `dependencies` to `devDependencies` in the offending package's package.json.
  2. Re-run scripts/buildTs.mjs to confirm the lint passes.
  3. 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

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


AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03). Data as JSON: /data/errors/be95985854b098e1.json. Report an issue: GitHub.