🚨 [security] Update jest 28.1.3 → 30.5.0 (major)


🚨 Your current dependencies have known security vulnerabilities 🚨

This dependency update fixes known security vulnerabilities. Please see the details below and assess their impact carefully. We recommend to merge and deploy this as soon as possible!


Here is everything you need to know about this upgrade. Please take a good look at what changed and the test results before merging this pull request.

What changed?

✳️ jest (28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ @​babel/code-frame (indirect, 7.18.6 → 7.29.7) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by 2 commits:

↗️ @​babel/compat-data (indirect, 7.18.8 → 7.29.7) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by 2 commits:

↗️ @​babel/core (indirect, 7.18.6 → 7.29.7) · Repo · Changelog

Security Advisories 🚨

🚨 @babel/core: Arbitrary File Read via sourceMappingURL Comment

Impact

Using @babel/core to compile maliciously crafted code can allow ab attacker to read any source map from the system that is running Babel, if these conditions are all true:

  • the attacker controls the input source code
  • the attacker can read the output source code
  • the attacker knows the path of the source map file that they want to read

Users that only compile trusted code are not impacted.

Patches

The vulnerability has been fixed in @babel/core@7.29.6 and @babel/core@8.0.0-rc.6.

Workarounds

Callers can mitigate the issue without upgrading by setting inputSourceMap: false in their Babel options.

Callers can also manually extract the #sourceMappingURL comment from the input source code, validate whether the source map that it links to is allowed to be read, and if it is pass an object to inputSourceMap (passing false when it's not).

Credits

Thanks Teodor-Cristian Radoi for reporting the vulnerability.

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by 2 commits:

↗️ @​babel/generator (indirect, 7.18.7 → 7.29.8) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by 8 commits:

↗️ @​babel/helper-compilation-targets (indirect, 7.18.6 → 7.29.7) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by 2 commits:

↗️ @​babel/helper-module-imports (indirect, 7.18.6 → 7.29.7) · Repo · Changelog

Release Notes

7.29.7

v7.29.7 (2026-05-25)

Re-release all packages with npm provenance attestations

7.27.1

v7.27.1 (2025-04-30)

Thanks @kermanx and @woaitsAryan for your first PRs!

👓 Spec Compliance

  • babel-parser
  • babel-parser, babel-types

🐛 Bug Fix

  • babel-plugin-proposal-destructuring-private, babel-plugin-proposal-do-expressions, babel-traverse
  • babel-helper-wrap-function, babel-plugin-transform-async-to-generator
    • #17251 Fix: propagate argument evaluation errors through async promise chain (@magic-akari)
  • babel-helper-remap-async-to-generator, babel-plugin-transform-async-to-generator
  • babel-helper-fixtures, babel-parser
    • #17233 Create ChainExpression within TSInstantiationExpression (@JLHwung)
  • babel-generator, babel-parser
    • #17226 Fill optional AST properties when both estree and typescript parser plugin are enabled (Part 2) (@JLHwung)
  • babel-parser
    • #17224 Fill optional AST properties when both estree and typescript parser plugin are enabled (Part 1) (@JLHwung)
    • #17080 Fix start of TSParameterProperty (@JLHwung)
  • babel-compat-data, babel-preset-env
  • babel-traverse
    • #17156 fix: Objects and arrays with multiple references should not be evaluated (@liuxingbaoyu)
  • babel-generator

💅 Polish

  • babel-plugin-bugfix-v8-spread-parameters-in-optional-chaining, babel-plugin-proposal-decorators, babel-plugin-transform-arrow-functions, babel-plugin-transform-class-properties, babel-plugin-transform-destructuring, babel-plugin-transform-object-rest-spread, babel-plugin-transform-optional-chaining, babel-plugin-transform-parameters, babel-traverse

🏠 Internal

  • babel-runtime-corejs2, babel-runtime-corejs3, babel-runtime
  • babel-compat-data, babel-preset-env
  • babel-compat-data, babel-standalone
  • babel-register
  • babel-helpers, babel-plugin-transform-async-generator-functions, babel-plugin-transform-regenerator, babel-preset-env, babel-runtime-corejs3
  • All packages

🔬 Output optimization

  • babel-helpers, babel-plugin-transform-modules-commonjs, babel-runtime-corejs3
  • babel-helpers, babel-plugin-transform-async-generator-functions, babel-plugin-transform-regenerator, babel-preset-env, babel-runtime-corejs3

Committers: 9

7.25.9

v7.25.9 (2024-10-22)

Thanks @victorenator for your first PR!

🐛 Bug Fix

  • babel-parser, babel-template, babel-types
  • babel-helper-compilation-targets, babel-preset-env
  • Other

🏠 Internal

  • babel-helper-transform-fixture-test-runner
  • Every package

🏃‍♀️ Performance

  • babel-parser, babel-types

Committers: 4

7.25.7

v7.25.7 (2024-10-02)

Thanks @DylanPiercey and @YuHyeonWook for your first PRs!

🐛 Bug Fix

💅 Polish

🏠 Internal

  • babel-core
  • babel-helper-compilation-targets, babel-helper-plugin-utils, babel-preset-env
  • babel-plugin-proposal-destructuring-private, babel-plugin-syntax-decimal, babel-plugin-syntax-import-reflection, babel-standalone
  • babel-generator

🏃‍♀️ Performance

Committers: 8

7.24.7

v7.24.7 (2024-06-05)

🐛 Bug Fix

  • babel-node
  • babel-traverse
  • babel-helper-transform-fixture-test-runner, babel-plugin-proposal-explicit-resource-management

🏠 Internal

  • babel-helpers, babel-runtime-corejs2, babel-runtime-corejs3, babel-runtime

Committers: 7

7.24.6

v7.24.6 (2024-05-24)

Thanks @amjed-98, @blakewilson, @coelhucas, and @SukkaW for your first PRs!

🐛 Bug Fix

  • babel-helper-create-class-features-plugin, babel-plugin-transform-class-properties
  • babel-core, babel-generator, babel-plugin-transform-modules-commonjs
  • babel-helper-create-class-features-plugin, babel-plugin-proposal-decorators
  • babel-helpers, babel-plugin-proposal-decorators, babel-runtime-corejs3
    • #16483 Fix: throw TypeError if addInitializer is called after finished (@JLHwung)
  • babel-parser, babel-plugin-transform-typescript

🏠 Internal

  • babel-core, babel-helpers, babel-plugin-transform-runtime, babel-preset-env, babel-runtime-corejs2, babel-runtime-corejs3, babel-runtime
  • babel-helpers
  • babel-cli, babel-helpers, babel-plugin-external-helpers, babel-plugin-proposal-decorators, babel-plugin-transform-class-properties, babel-plugin-transform-modules-commonjs, babel-plugin-transform-modules-systemjs, babel-plugin-transform-runtime, babel-preset-env, babel-runtime-corejs2, babel-runtime-corejs3, babel-runtime
  • babel-parser, babel-traverse
  • Other

Committers: 9

7.24.3

v7.24.3 (2024-03-20)

🐛 Bug Fix

  • babel-helper-module-imports
    • #16370 fix: do not inject the same imported identifier multiple times (@ota-meshi)

Committers: 2

7.24.1

v7.24.1 (2024-03-19)

🐛 Bug Fix

  • babel-helper-create-class-features-plugin, babel-plugin-proposal-decorators
  • babel-plugin-proposal-decorators, babel-plugin-proposal-json-modules, babel-plugin-transform-async-generator-functions, babel-plugin-transform-regenerator, babel-plugin-transform-runtime, babel-preset-env
  • babel-helper-create-class-features-plugin, babel-plugin-proposal-decorators, babel-plugin-proposal-pipeline-operator, babel-plugin-transform-class-properties
  • babel-helper-create-class-features-plugin, babel-helper-replace-supers, babel-plugin-proposal-decorators, babel-plugin-transform-class-properties

📝 Documentation

🏠 Internal

  • babel-code-frame, babel-highlight
  • babel-helper-fixtures, babel-helpers, babel-plugin-bugfix-safari-id-destructuring-collision-in-function-expression, babel-plugin-proposal-pipeline-operator, babel-plugin-transform-unicode-sets-regex, babel-preset-env, babel-preset-flow
  • babel-helper-module-imports, babel-plugin-proposal-import-wasm-source, babel-plugin-proposal-json-modules, babel-plugin-proposal-record-and-tuple, babel-plugin-transform-react-jsx-development, babel-plugin-transform-react-jsx
  • Other

🔬 Output optimization

  • babel-helper-replace-supers, babel-plugin-transform-class-properties, babel-plugin-transform-classes, babel-plugin-transform-parameters, babel-plugin-transform-runtime
  • babel-plugin-transform-class-properties, babel-plugin-transform-classes
  • babel-plugin-proposal-decorators, babel-plugin-transform-class-properties, babel-plugin-transform-object-rest-spread, babel-traverse
  • babel-core, babel-plugin-external-helpers, babel-plugin-proposal-decorators, babel-plugin-proposal-function-bind, babel-plugin-transform-class-properties, babel-plugin-transform-classes, babel-plugin-transform-flow-comments, babel-plugin-transform-flow-strip-types, babel-plugin-transform-function-name, babel-plugin-transform-modules-systemjs, babel-plugin-transform-parameters, babel-plugin-transform-private-property-in-object, babel-plugin-transform-react-jsx, babel-plugin-transform-runtime, babel-plugin-transform-spread, babel-plugin-transform-typescript, babel-preset-env

Committers: 4

7.22.15

v7.22.15 (2023-09-04)

🐛 Bug Fix

🏠 Internal

Committers: 4

7.22.5

v7.22.5 (2023-06-08)

🐛 Bug Fix

  • babel-preset-env, babel-standalone

💅 Polish

Committers: 4

7.21.4

v7.21.4 (2023-03-31)

🐛 Bug Fix

  • babel-core, babel-helper-module-imports, babel-preset-typescript
  • babel-generator
    • #15496 Fix compact printing of non-null assertion operators (@rtsao)

💅 Polish

  • babel-helper-create-class-features-plugin, babel-plugin-proposal-class-properties, babel-plugin-transform-typescript, babel-traverse

🏠 Internal

  • Other
  • babel-parser
  • babel-code-frame, babel-highlight

Committers: 6

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 2 commits:

↗️ @​babel/helper-module-transforms (indirect, 7.18.8 → 7.29.7) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by 2 commits:

↗️ @​babel/helper-plugin-utils (indirect, 7.18.6 → 7.29.7) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by 2 commits:

↗️ @​babel/helper-validator-identifier (indirect, 7.18.6 → 7.29.7) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by 2 commits:

↗️ @​babel/helpers (indirect, 7.18.6 → 7.29.7) · Repo · Changelog

Security Advisories 🚨

🚨 Babel has inefficient RegExp complexity in generated code with .replace when transpiling named capturing groups

Impact

When using Babel to compile regular expression named capturing groups, Babel will generate a polyfill for the .replace method that has quadratic complexity on some specific replacement pattern strings (i.e. the second argument passed to .replace).

Your generated code is vulnerable if all the following conditions are true:

  • You use Babel to compile regular expression named capturing groups
  • You use the .replace method on a regular expression that contains named capturing groups
  • Your code uses untrusted strings as the second argument of .replace

If you are using @babel/preset-env with the targets option, the transform that injects the vulnerable code is automatically enabled if:

  • you use duplicated named capturing groups, and target any browser older than Chrome/Edge 126, Opera 112, Firefox 129, Safari 17.4, or Node.js 23
  • you use any named capturing groups, and target any browser older than Chrome 64, Opera 71, Edge 79, Firefox 78, Safari 11.1, or Node.js 10

You can verify what transforms @babel/preset-env is using by enabling the debug option.

Patches

This problem has been fixed in @babel/helpers and @babel/runtime 7.26.10 and 8.0.0-alpha.17, please upgrade. It's likely that you do not directly depend on @babel/helpers, and instead you depend on @babel/core (which itself depends on @babel/helpers). Upgrading to @babel/core 7.26.10 is not required, but it guarantees that you are on a new enough @babel/helpers version.

Please note that just updating your Babel dependencies is not enough: you will also need to re-compile your code.

Workarounds

If you are passing user-provided strings as the second argument of .replace on regular expressions that contain named capturing groups, validate the input and make sure it does not contain the substring $< if it's then not followed by > (possibly with other characters in between).

References

This vulnerability was reported and fixed in #17173.

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by 2 commits:

↗️ @​babel/parser (indirect, 7.18.8 → 7.29.8) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by 8 commits:

↗️ @​babel/plugin-syntax-typescript (indirect, 7.18.6 → 7.29.7) · Repo · Changelog

Release Notes

7.29.7

v7.29.7 (2026-05-25)

Re-release all packages with npm provenance attestations

7.27.1

v7.27.1 (2025-04-30)

Thanks @kermanx and @woaitsAryan for your first PRs!

👓 Spec Compliance

  • babel-parser
  • babel-parser, babel-types

🐛 Bug Fix

  • babel-plugin-proposal-destructuring-private, babel-plugin-proposal-do-expressions, babel-traverse
  • babel-helper-wrap-function, babel-plugin-transform-async-to-generator
    • #17251 Fix: propagate argument evaluation errors through async promise chain (@magic-akari)
  • babel-helper-remap-async-to-generator, babel-plugin-transform-async-to-generator
  • babel-helper-fixtures, babel-parser
    • #17233 Create ChainExpression within TSInstantiationExpression (@JLHwung)
  • babel-generator, babel-parser
    • #17226 Fill optional AST properties when both estree and typescript parser plugin are enabled (Part 2) (@JLHwung)
  • babel-parser
    • #17224 Fill optional AST properties when both estree and typescript parser plugin are enabled (Part 1) (@JLHwung)
    • #17080 Fix start of TSParameterProperty (@JLHwung)
  • babel-compat-data, babel-preset-env
  • babel-traverse
    • #17156 fix: Objects and arrays with multiple references should not be evaluated (@liuxingbaoyu)
  • babel-generator

💅 Polish

  • babel-plugin-bugfix-v8-spread-parameters-in-optional-chaining, babel-plugin-proposal-decorators, babel-plugin-transform-arrow-functions, babel-plugin-transform-class-properties, babel-plugin-transform-destructuring, babel-plugin-transform-object-rest-spread, babel-plugin-transform-optional-chaining, babel-plugin-transform-parameters, babel-traverse

🏠 Internal

  • babel-runtime-corejs2, babel-runtime-corejs3, babel-runtime
  • babel-compat-data, babel-preset-env
  • babel-compat-data, babel-standalone
  • babel-register
  • babel-helpers, babel-plugin-transform-async-generator-functions, babel-plugin-transform-regenerator, babel-preset-env, babel-runtime-corejs3
  • All packages

🔬 Output optimization

  • babel-helpers, babel-plugin-transform-modules-commonjs, babel-runtime-corejs3
  • babel-helpers, babel-plugin-transform-async-generator-functions, babel-plugin-transform-regenerator, babel-preset-env, babel-runtime-corejs3

Committers: 9

7.25.9

v7.25.9 (2024-10-22)

Thanks @victorenator for your first PR!

🐛 Bug Fix

  • babel-parser, babel-template, babel-types
  • babel-helper-compilation-targets, babel-preset-env
  • Other

🏠 Internal

  • babel-helper-transform-fixture-test-runner
  • Every package

🏃‍♀️ Performance

  • babel-parser, babel-types

Committers: 4

7.25.7

v7.25.7 (2024-10-02)

Thanks @DylanPiercey and @YuHyeonWook for your first PRs!

🐛 Bug Fix

💅 Polish

🏠 Internal

  • babel-core
  • babel-helper-compilation-targets, babel-helper-plugin-utils, babel-preset-env
  • babel-plugin-proposal-destructuring-private, babel-plugin-syntax-decimal, babel-plugin-syntax-import-reflection, babel-standalone
  • babel-generator

🏃‍♀️ Performance

Committers: 8

7.25.4

v7.25.4 (2024-08-22)

🐛 Bug Fix

  • babel-traverse
  • babel-helper-create-class-features-plugin, babel-plugin-proposal-decorators
  • babel-types
  • babel-generator

💅 Polish

  • babel-generator, babel-plugin-proposal-decorators, babel-plugin-proposal-destructuring-private, babel-plugin-proposal-pipeline-operator, babel-plugin-transform-class-properties, babel-plugin-transform-destructuring, babel-plugin-transform-optional-chaining, babel-plugin-transform-private-methods, babel-plugin-transform-private-property-in-object, babel-plugin-transform-typescript, babel-runtime-corejs2, babel-runtime, babel-traverse
  • babel-generator, babel-plugin-transform-class-properties
  • babel-generator, babel-plugin-proposal-decorators, babel-plugin-proposal-destructuring-private, babel-plugin-transform-object-rest-spread

🔬 Output optimization

Committers: 4

7.24.7

v7.24.7 (2024-06-05)

🐛 Bug Fix

  • babel-node
  • babel-traverse
  • babel-helper-transform-fixture-test-runner, babel-plugin-proposal-explicit-resource-management

🏠 Internal

  • babel-helpers, babel-runtime-corejs2, babel-runtime-corejs3, babel-runtime

Committers: 7

7.24.6

v7.24.6 (2024-05-24)

Thanks @amjed-98, @blakewilson, @coelhucas, and @SukkaW for your first PRs!

🐛 Bug Fix

  • babel-helper-create-class-features-plugin, babel-plugin-transform-class-properties
  • babel-core, babel-generator, babel-plugin-transform-modules-commonjs
  • babel-helper-create-class-features-plugin, babel-plugin-proposal-decorators
  • babel-helpers, babel-plugin-proposal-decorators, babel-runtime-corejs3
    • #16483 Fix: throw TypeError if addInitializer is called after finished (@JLHwung)
  • babel-parser, babel-plugin-transform-typescript

🏠 Internal

  • babel-core, babel-helpers, babel-plugin-transform-runtime, babel-preset-env, babel-runtime-corejs2, babel-runtime-corejs3, babel-runtime
  • babel-helpers
  • babel-cli, babel-helpers, babel-plugin-external-helpers, babel-plugin-proposal-decorators, babel-plugin-transform-class-properties, babel-plugin-transform-modules-commonjs, babel-plugin-transform-modules-systemjs, babel-plugin-transform-runtime, babel-preset-env, babel-runtime-corejs2, babel-runtime-corejs3, babel-runtime
  • babel-parser, babel-traverse
  • Other

Committers: 9

7.24.1

v7.24.1 (2024-03-19)

🐛 Bug Fix

  • babel-helper-create-class-features-plugin, babel-plugin-proposal-decorators
  • babel-plugin-proposal-decorators, babel-plugin-proposal-json-modules, babel-plugin-transform-async-generator-functions, babel-plugin-transform-regenerator, babel-plugin-transform-runtime, babel-preset-env
  • babel-helper-create-class-features-plugin, babel-plugin-proposal-decorators, babel-plugin-proposal-pipeline-operator, babel-plugin-transform-class-properties
  • babel-helper-create-class-features-plugin, babel-helper-replace-supers, babel-plugin-proposal-decorators, babel-plugin-transform-class-properties

📝 Documentation

🏠 Internal

  • babel-code-frame, babel-highlight
  • babel-helper-fixtures, babel-helpers, babel-plugin-bugfix-safari-id-destructuring-collision-in-function-expression, babel-plugin-proposal-pipeline-operator, babel-plugin-transform-unicode-sets-regex, babel-preset-env, babel-preset-flow
  • babel-helper-module-imports, babel-plugin-proposal-import-wasm-source, babel-plugin-proposal-json-modules, babel-plugin-proposal-record-and-tuple, babel-plugin-transform-react-jsx-development, babel-plugin-transform-react-jsx
  • Other

🔬 Output optimization

  • babel-helper-replace-supers, babel-plugin-transform-class-properties, babel-plugin-transform-classes, babel-plugin-transform-parameters, babel-plugin-transform-runtime
  • babel-plugin-transform-class-properties, babel-plugin-transform-classes
  • babel-plugin-proposal-decorators, babel-plugin-transform-class-properties, babel-plugin-transform-object-rest-spread, babel-traverse
  • babel-core, babel-plugin-external-helpers, babel-plugin-proposal-decorators, babel-plugin-proposal-function-bind, babel-plugin-transform-class-properties, babel-plugin-transform-classes, babel-plugin-transform-flow-comments, babel-plugin-transform-flow-strip-types, babel-plugin-transform-function-name, babel-plugin-transform-modules-systemjs, babel-plugin-transform-parameters, babel-plugin-transform-private-property-in-object, babel-plugin-transform-react-jsx, babel-plugin-transform-runtime, babel-plugin-transform-spread, babel-plugin-transform-typescript, babel-preset-env

Committers: 4

7.23.3

v7.23.3 (2023-11-09)

🐛 Bug Fix

  • babel-plugin-transform-typescript
  • babel-generator
  • babel-compat-data, babel-plugin-bugfix-v8-static-class-fields-redefine-readonly, babel-preset-env
  • babel-plugin-transform-object-super
  • babel-helper-module-transforms, babel-plugin-transform-modules-amd, babel-plugin-transform-modules-commonjs, babel-plugin-transform-modules-umd

📝 Documentation

  • #16044 docs: Update links in @babel/eslint-parser README (@aryehb)

🏠 Internal

  • babel-core, babel-preset-env

🏃‍♀️ Performance

🔬 Output optimization

  • babel-plugin-transform-computed-properties

Committers: 9

7.22.5

v7.22.5 (2023-06-08)

🐛 Bug Fix

  • babel-preset-env, babel-standalone

💅 Polish

Committers: 4

7.21.4

v7.21.4 (2023-03-31)

🐛 Bug Fix

  • babel-core, babel-helper-module-imports, babel-preset-typescript
  • babel-generator
    • #15496 Fix compact printing of non-null assertion operators (@rtsao)

💅 Polish

  • babel-helper-create-class-features-plugin, babel-plugin-proposal-class-properties, babel-plugin-transform-typescript, babel-traverse

🏠 Internal

  • Other
  • babel-parser
  • babel-code-frame, babel-highlight

Committers: 6

7.20.0

v7.20.0 (2022-10-27)

Thanks @oceandrama for your first PR!

🚀 New Feature

  • babel-compat-data, babel-helper-compilation-targets, babel-preset-env
  • babel-plugin-syntax-typescript
  • babel-generator, babel-parser, babel-plugin-syntax-explicit-resource-management, babel-plugin-transform-block-scoping, babel-plugin-transform-destructuring, babel-standalone, babel-traverse, babel-types
    • #14968 Parse using declaration (explicit resource management) (@JLHwung)
  • babel-generator, babel-parser, babel-plugin-syntax-import-reflection, babel-standalone, babel-types
  • babel-generator, babel-helper-skip-transparent-expression-wrappers, babel-parser, babel-plugin-transform-typescript, babel-traverse, babel-types

🐛 Bug Fix

🏠 Internal

  • babel-helpers, babel-node, babel-plugin-proposal-async-generator-functions, babel-plugin-transform-regenerator, babel-preset-env, babel-runtime-corejs2, babel-runtime-corejs3, babel-runtime

Committers: 5

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 2 commits:

↗️ @​babel/template (indirect, 7.18.6 → 7.29.7) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by 2 commits:

↗️ @​babel/traverse (indirect, 7.18.8 → 7.29.8) · Repo · Changelog

Security Advisories 🚨

🚨 Babel vulnerable to arbitrary code execution when compiling specifically crafted malicious code

Impact

Using Babel to compile code that was specifically crafted by an attacker can lead to arbitrary code execution during compilation, when using plugins that rely on the path.evaluate()or path.evaluateTruthy() internal Babel methods.

Known affected plugins are:

  • @babel/plugin-transform-runtime
  • @babel/preset-env when using its useBuiltIns option
  • Any "polyfill provider" plugin that depends on @babel/helper-define-polyfill-provider, such as babel-plugin-polyfill-corejs3, babel-plugin-polyfill-corejs2, babel-plugin-polyfill-es-shims, babel-plugin-polyfill-regenerator

No other plugins under the @babel/ namespace are impacted, but third-party plugins might be.

Users that only compile trusted code are not impacted.

Patches

The vulnerability has been fixed in @babel/traverse@7.23.2.

Babel 6 does not receive security fixes anymore (see Babel's security policy), hence there is no patch planned for babel-traverse@6.

Workarounds

  • Upgrade @babel/traverse to v7.23.2 or higher. You can do this by deleting it from your package manager's lockfile and re-installing the dependencies. @babel/core >=7.23.2 will automatically pull in a non-vulnerable version.
  • If you cannot upgrade @babel/traverse and are using one of the affected packages mentioned above, upgrade them to their latest version to avoid triggering the vulnerable code path in affected @babel/traverse versions:
    • @babel/plugin-transform-runtime v7.23.2
    • @babel/preset-env v7.23.2
    • @babel/helper-define-polyfill-provider v0.4.3
    • babel-plugin-polyfill-corejs2 v0.4.6
    • babel-plugin-polyfill-corejs3 v0.8.5
    • babel-plugin-polyfill-es-shims v0.10.0
    • babel-plugin-polyfill-regenerator v0.5.3
Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by 8 commits:

↗️ @​babel/types (indirect, 7.18.8 → 7.29.8) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by 8 commits:

↗️ @​istanbuljs/schema (indirect, 0.1.3 → 0.1.6) · Repo · Changelog

Release Notes

0.1.6

0.1.6 (2026-04-13)

Bug Fixes

  • Undo change to schema in 0.1.x series (440f977)

0.1.5

0.1.5 (2026-04-13)

Bug Fixes

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 7 commits:

↗️ @​jest/console (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ @​jest/core (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ @​jest/environment (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ @​jest/fake-timers (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

30.5.0

On a personal note: King Harald V of Norway passed away this morning. He ascended the throne 35 years ago, two months before I was born. This release is dedicated to his memory. Hvil i fred 🇳🇴


This is a big release. It touches jest-runtime, jest-resolve and jest-haste-map in many places, and with this many changes there might be regressions 😬. If your suite behaves differently after upgrading, please open an issue.

Highlights

whenCalledWith

Mock functions can now configure return values per argument list, contributed by @timkindberg (#16053):

const fn = jest.fn();
fn.whenCalledWith('apple').mockReturnValue('red');
fn.whenCalledWith('banana').mockReturnValue('yellow');
fn.whenCalledWith(expect.any(Number)).mockReturnValue('numeric');

fn('apple'); // 'red'
fn('banana'); // 'yellow'
fn(42); // 'numeric'
fn('grape'); // undefined

The returned object is a real Mock, so mockReturnValueOnce, mockResolvedValue, mockImplementation etc. all chain here too. Argument slots accept literals or any asymmetric matcher, with the same equality semantics as toHaveBeenCalledWith(). Calls that match nothing fall through to the base mock. See the Mock Functions docs for matching and precedence details.

Describe-level retries

jest.retryTimes() can now retry a whole describe block instead of a single test, contributed by @soltonigiri (#16322). Each attempt reruns the block's beforeAll/afterAll hooks, child tests and nested describes, which helps when tests in a block depend on shared state:

describe('workflow', () => {
  jest.retryTimes(3, {entireDescribe: true});

  test('first step', () => {});
  test('second step', () => {}); // a failure retries the entire block
});

New file watcher

The non-watchman path of jest-haste-map is rewritten. @parcel/watcher replaces the homegrown NodeWatcher and FSEventsWatcher (#16188), and fdir replaces the hand-rolled directory recursion in the crawler (#16187). A batch of fixes also makes watching and indexing survive locked files on Windows, watchman failures, and duplicate manual mocks (#16295, #16358, #16355, #16360).

If you can, please run your suite with --no-watchman (in and out of watch mode) to exercise the new crawler and watchers, and report anything odd 👍

Long-requested dependency updates

  • babel-plugin-istanbul is updated to v8 (#16049)
  • glob is updated to v13 (#16397)
  • source-map-support is replaced with an implementation in @jest/source-map (#16327). This fixes a memory leak where source-map-support's process-global caches pinned every finished test file's sandbox. Source maps also survive environment teardown, --testLocationInResults looks up the right column, and scheme-prefixed sources like webpack:/// are kept as-is.

Performance

  • Warm module resolution costs about a third of what it did, and repeated work is gone from the resolution hot path (#16373, #16371).
  • Per-require overhead in jest-runtime is cut: module ID resolution is skipped when no mock can apply, and core modules answer before the manual-mock probe (#16376).
  • jest-snapshot loads babel, semver and synckit lazily, so every test process loads ~200 fewer modules (#16387).
  • jest-haste-map caches the watchman socket path, so warm runs spawn no watchman processes (#16386), and reuses cached metadata for duplicated haste names instead of re-parsing them on every startup (#16351).

More new APIs

  • Snapshot failures expose the .snap file path as matcherResult.snapshotPath in failureDetails (#16374).
  • --collectTests expands test.each/describe.each cases and reports per-status counts plus a summary line that matches a real run (#16259).
  • AggregateError inner errors and nested cause chains render with code frames and per-level indentation, and are included in --json output, retryReasons and reporter annotations (#16316).

ESM

A long list of fixes brings jest-runtime's module system closer to Node's:

  • Automocking and manual __mocks__ files now apply to ESM on Node 24.9+. Static imports, dynamic import() and require() of an ESM file generate an automock from the real module's namespace instead of failing with "Attempting to import a mock without a factory" (#16391).
  • Many jest.unstable_mockModule gaps are closed: mocks apply when the mocked file is require()d directly, async factories run once and fail the import instead of crashing the worker 😅, and mocks made inside jest.isolateModules stay scoped to that block (#16389, #16365).
  • require(esm), CJS/ESM interop, import.meta, data: URIs and error ordering now match Node in dozens of edge cases. See the Fixes section for the full list (#16364 through #16391).
  • The module-sync export condition resolves, so packages that expose their ESM entry point for require() load the same file Node picks (#16336).

The intentional divergences from Node's module system are now documented on the ECMAScript Modules page (#16368).

Resolver

  • The default resolver honors Node's --preserve-symlinks / NODE_PRESERVE_SYMLINKS (#16260).
  • moduleNameMapper applies to both spellings of core module specifiers (fs and node:fs), and builtins that only exist prefixed (node:sqlite, node:test) resolve asynchronously (#16390, #16388).
  • A user resolver can be written as an ES module (#16332).

On top of the highlights there are ~60 fixes across jest-circus, jest-haste-map, jest-config, jest-mock and the transform cache keys. See the full changelog below 😀


Features

  • [@jest/expect-utils, jest-mock] Add mockFn.whenCalledWith(...args) for configuring return values per argument list, with first-class asymmetric-matcher support (#16053)
  • [@jest/expect-utils] Export AsymmetricMatcher and FunctionParameters types (previously private to expect) (#16053)
  • [jest-circus, jest-core, jest-jasmine2, jest-test-result, jest-types] --collectTests now expands test.each/describe.each cases and reports per-status counts (skipped/todo via the new wouldRun flag for selected tests) plus a summary line that match a real run, including under --testNamePattern and .only/fdescribe focus on both the circus and jasmine2 runners (#16259)
  • [jest-circus, jest-environment, jest-runtime, jest-types] Add describe-level retries via jest.retryTimes(..., {entireDescribe: true}) (#16322)
  • [jest-circus, jest-message-util, jest-reporters, jest-types] Add retryMessages to AssertionResult and export formatErrorStack, so the retry log renders nested cause and AggregateError sections with code frames instead of serialized [cause]:/[errors]: markers (#16316)
  • [jest-circus, jest-types] Add unhandledErrorsDetailed to Circus.RunResult, so an unhandled rejection reports its cause chain and AggregateError entries with code frames instead of a pre-serialized stack (#16316)
  • [jest-haste-map] Replace NodeWatcher and FSEventsWatcher with @parcel/watcher for the non-watchman watch path (#16188)
  • [jest-resolve] Bump unrs-resolver to 1.12.1, remove jest-pnp-resolver and unnecessary checks (#15721)
  • [jest-resolve] Honor Node's --preserve-symlinks / NODE_PRESERVE_SYMLINKS in the default resolver by passing symlinks: false to unrs-resolver (#16260)
  • [jest-runtime] Apply automocking and manual __mocks__ files to synchronously evaluable ESM graphs on Node 24.9+ - static imports, dynamic import() and require() of an ESM file now generate an automock from the real module's namespace instead of failing with "Attempting to import a mock without a factory". Graphs that need async evaluation (top-level await) or an async-only resolver or transformer still throw (#16391)
  • [jest-runtime] Route process.getBuiltinModule through the sandbox, so it returns the sandbox process and the hooked node:module instead of the host's (#16391)
  • [jest-runtime] Throw an actionable error from module.register() and module.registerHooks() inside a test - the hooks attached to the loader running Jest itself, never saw the sandboxed requires they were meant for, and stayed registered for every later test file in the worker (#16391)
  • [jest-runtime] Surface resolution and import-attribute errors in an ESM graph before executing any of its CJS dependencies on Node 24.9+, matching Node's run-nothing-on-a-broken-graph behavior; the legacy loader on older versions keeps its linking-time execution order (#16391)
  • [jest-runtime] Throw ERR_SOURCE_PHASE_NOT_DEFINED with an actionable message for import source and import.source(), instead of failing at instantiation with V8's bare "Source phase import object is not defined" (#16391)
  • [jest-runtime] Emit the JSON-without-import-attribute deprecation warning once per test file instead of once per worker, so it is no longer silently swallowed for every file after the first (#16391)
  • [jest-runtime] Set import.meta.main to true in the test file and false in every module it loads, matching Node 24+ (#16367)
  • [jest-runtime] Resolve the module-sync export condition, so a package that exposes its ESM entry point for require() loads the same file Node would (#16336)
  • [jest-snapshot] Add external snapshot paths to custom reporter failure details (#16374)

Fixes

  • [jest-console, jest-reporters] CustomConsole now buffers console output so TestResult.console is populated for reporters when verbose is enabled, while GitHubActionsReporter avoids replaying buffered output in verbose mode (#16155)
  • [expect, jest-message-util, jest-pattern, jest-regex-util, jest-util] Revert node: protocol imports to restore webpack/browser-bundle compatibility (#16167)
  • [expect] Widen toMatchObject and objectContaining parameter type from Record<string, unknown> to object so class instances are accepted (#16196)
  • [jest-circus] Call a generator test body with the shared test context, so this matches what a regular test function receives (#16347)
  • [jest-circus] Capture the error listeners of the parent process instead of the in-sandbox process, so listeners registered before the test file survive teardown and sandbox listeners no longer leak onto the parent (#16347)
  • [jest-circus] Clear currentlyRunningTest after skipped and todo tests (#16342)
  • [jest-circus] Prevent late done() callbacks from affecting later test or hook invocations (#16343)
  • [jest-circus, jest-jasmine2] Honor --expand when formatting node:assert failures, instead of always collapsing the diff (#16347)
  • [jest-circus, jest-jasmine2, jest-message-util] Serialize the inner errors of an AggregateError into failureMessages, retryReasons and unhandledErrors, so --json output and reporter annotations include them (#16316)
  • [jest-circus, jest-snapshot] Keep snapshot state and counts correct when a test retries (#16344)
  • [@jest/create-cache-key-function] Include the caller support flags in the generated key, so a transformer that emits ESM or CJS based on them no longer shares one cache entry between the two (#16331)
  • [@jest/create-cache-key-function] Include the stringified project config in the generated key, so editing a transformer's own settings invalidates what it cached (#16331)
  • [@jest/transform] Include the caller support flags in a transform's cache key, so a file transformed both as ESM and as CJS no longer serves one shape's output for the other (#16331)
  • [jest-config] Add missing findRelatedTests, outputFile, and replname entries to ValidConfig so they no longer trigger spurious "Unknown option" warnings (#16224)
  • [jest-config] Use --config for the global config when multiple --projects are specified (#16273)
  • [jest-core] Serialize bigint values in --json and --outputFile output as their literal form (4n), instead of failing the run with TypeError: Do not know how to serialize a BigInt (#16338)
  • [jest-core] Do not report a CustomGC async resource (used by N-API addons such as napi-rs for per-isolate GC bookkeeping) as an open handle, since it is napi_unref'd by the addon and can never keep the event loop alive (#16379)
  • [jest-each] Keep a $&, $`, $' or $$ inside a %p param value out of the replacement, so the title shows the value instead of the text around it (#16338)
  • [jest-each] Interpolate a bigint into a %j title as its literal form ("4n") at any depth, instead of throwing TypeError: Do not know how to serialize a BigInt while collecting the tests (#16338)
  • [jest-environment, jest-runtime] Bind sandboxInjectedGlobals to the right values when injectGlobals is false, instead of shifting every one of them by a position (#16377)
  • [jest-environment-node, jest-util] Only warn about a conflicting globalsCleanup mode when one was explicitly configured, and follow the mode that is actually in effect (#16323)
  • [jest-environment-node, jest-util] Stop resolving lazy globals when setting up an environment, so Node 26's builtin module globals are no longer loaded (and no longer emit their deprecation warnings) for every test file (#16324)
  • [jest-haste-map] Keep watch mode alive when an outside process briefly makes a file unreadable on Windows, instead of tearing the watcher down on EPERM (#16295)
  • [jest-haste-map] Keep indexing when an outside process holds a file open on Windows, instead of failing the whole crawl on EPERM (#16358)
  • [jest-haste-map] Keep a duplicated manual mock resolving when the file it pointed at is deleted in watch mode (#16360)
  • [jest-haste-map] Shut the worker farm down when a duplicate manual mock aborts the build under throwOnModuleCollision (#16354)
  • [jest-haste-map] Attach the watchman client's error listener before the first command, so a watchman failure falls back to the node crawler instead of crashing on an unhandled error event, and always end the client (#16355)
  • [jest-haste-map] Stop delivering watch events after WatchmanWatcher is closed, and route its warnings through the configured console (#16355)
  • [jest-haste-map] Restore the nested duplicates index correctly in ModuleMap.fromJSON, so a haste collision reported inside a test worker raises DuplicateHasteCandidatesError instead of a TypeError (#16353)
  • [jest-haste-map] Match watched files on a full extension, so moduleFileExtensions: ['js'] no longer accepts foo.mjs (#16352)
  • [jest-haste-map] Delimit the fields that make up the haste map cache key, so two different option sets cannot hash to the same cache file (#16352)
  • [jest-message-util] Print the inner errors of an AggregateError thrown inside a test (#16316)
  • [jest-message-util] Indent nested cause and AggregateError sections of a test failure by one level per depth, so the nesting is legible instead of rendering flat (#16316)
  • [jest-message-util] Color stack traces line by line so blank lines stay blank (#16316)
  • [jest-message-util] Detect Jest's own frames without assuming the checkout directory's name, and cover @jest/* packages, so stack traces and code frames point at user code (#16326)
  • [jest-mock] mockResolvedValue / mockRejectedValue now see all overload return types, so a Promise-returning overload survives even when a later overload returns a non-Promise (e.g. pg.Client['end']) (#16237)
  • [@jest-environment/jsdom-abstract] Make @types/jsdom a peer dependency (#16166)
  • [jest-mock] Remove the leftover own accessor descriptor when restoring a spyOn of an inherited getter or setter, so the instance keeps reflecting the prototype (#16226)
  • [jest-resolve] Include extensionsToTreatAsEsm in the shouldLoadAsEsm cache key, so projects with different extension lists don't read each other's answers (#16369)
  • [jest-resolve] Make getModuleIDAsync build and cache data: URI module IDs the same way as getModuleID (#16370)
  • [jest-resolve] Keep the node: prefix when resolving a core module asynchronously, so a builtin that only exists prefixed (node:sea, node:sqlite, node:test, node:test/reporters) resolves instead of failing as a missing bare package (#16388)
  • [jest-resolve] Look up manual mocks for node: protocol specifiers under the unprefixed name they are stored as (#16388)
  • [jest-resolve] Apply moduleNameMapper consistently to both spellings of core module specifiers (fs vs node:fs) (#16390)
  • [jest-resolve] Keep virtual and ordinary mock module IDs isolated across test files (#16296)
  • [jest-resolve] Guard missing require.resolve.paths (#16052)
  • [jest-resolve, jest-config, jest-runner] Support a user resolver written as an ES module (#16332)
  • [jest-resolve, jest-runtime] Throw the CJS parse error for ESM syntax in a "type": "commonjs" package or a .cjs file instead of loading it as ESM, matching Node (#16368)
  • [@jest/source-map] Keep source map sources that name a scheme, such as webpack:///, instead of resolving them into a path that does not exist (#16327)
  • [@jest/source-map] Look up --testLocationInResults positions at the right column, and keep a mapping to the first column instead of discarding it (#16327)
  • [@jest/source-map] Warn when a source map cannot be parsed, instead of silently leaving its frames untranslated (#16327)
  • [jest-runner, @jest/source-map] Keep a source-mapped stack for an error thrown after the test environment was torn down (#16327)
  • [jest-runtime, @jest/source-map] Keep source maps past teardown and past the next test file's install, so a stack from a file no earlier stack mentioned still points at the original source (#16330)
  • [jest-runtime] Report that no coverage was collected when getAllV8CoverageInfoCopy is called after teardown, instead of returning an empty result (#16385)
  • [jest-runtime] Cache a CJS module's parsed exports before walking its re-exports, so two modules that re-export each other no longer overflow the stack when imported from ESM (#16363)
  • [jest-runtime] Keep a re-exported ES module's parse failure from marking the re-exporting CommonJS file as ESM, so module.exports = require('./dep.mjs') loads instead of failing with module is not defined (#16363)
  • [jest-runtime] Scope module mocks instantiated inside jest.isolateModules/isolateModulesAsync to that block, so a mock first imported there no longer outlives it - matching how CommonJS mocks already behave (#16365)
  • [jest-runtime] Suspend module isolation while generating an automock, so loading the real module to read its shape no longer populates the isolated registry (#16365)
  • [jest-runtime] Check a cached ES module's status before require() returns it, so a module whose evaluation threw rethrows that error and one left linked by a failed sibling is evaluated instead of returning uninitialized bindings (#16364)
  • [jest-runtime] Report the original ERR_REQUIRE_ASYNC_MODULE when a require() of a top-level-await graph is retried, instead of a spurious "concurrent import()" error (#16364)
  • [jest-runtime] Throw the evaluation error when another caller's import() of the same module failed while we awaited it, instead of resolving with the errored module (#16364)
  • [jest-runtime] Mark the result of require()ing an ES module that has a default export with __esModule: true through a live-binding facade, and serve the same object from require.cache, matching Node (#16367)
  • [jest-runtime] Provide a CommonJS module's exports under the 'module.exports' named export when imported from ESM, matching Node 23+ (#16367)
  • [jest-runtime] Give the test file itself a non-null require.main (#16367)
  • [jest-runtime] Populate module.children with the modules a file loads, matching Node (#16368)
  • [jest-runtime] Provide import.meta.resolve and import.meta.jest in data: URI modules, accept any-case mediatype parameters, and use Node's error codes for invalid data: URIs (#16368)
  • [jest-runtime] Key ES modules by full URL, so query and fragment suffixes create the same module instances as Node and show up in import.meta.url (#16375)
  • [jest-runtime] Share modules between overlapping graphs when a CommonJS module require()s an ES module mid-load, instead of evaluating shared dependencies twice (#16375)
  • [jest-runtime] Throw ERR_REQUIRE_CYCLE_MODULE like Node when a CommonJS module require()s an ES module that is still being loaded, instead of evaluating the module a second time (#16366)
  • [jest-runtime] Key builtin modules in the ESM registry by one canonical specifier (#16341)
  • [jest-runtime] import.meta.resolve() for a builtin uses its node: specifier (#16341)
  • [jest-runtime] Fall back to native ESM when a .js file contains ESM syntax but has no "type":"module" marker (#16152)
  • [jest-runtime] Allow require() of ESM-marked files on Node < 24.9 via transform fallback (#16244)
  • [jest-runtime, @jest/transform] Surface actionable ERR_REQUIRE_ESM error for files with untransformed ESM syntax instead of the generic "unexpected token" message (#16244)
  • [jest-runtime] Support older test environments whose moduleMocker does not implement clearMocksOnScope (#16169)
  • [jest-runtime] Apply jest.unstable_mockModule when the mocked file itself is require()d, not only when it is imported as a dependency (#16389)
  • [jest-runtime] Apply jest.unstable_mockModule to statically imported data: URIs on Node 24.9+, matching dynamic import() (#16389)
  • [jest-runtime] Run an async jest.unstable_mockModule factory once per module instead of twice, and fail the import instead of crashing the worker when the factory rejects (#16389)
  • [jest-runtime] Hide a require(esm) module that failed to evaluate from require.cache, as Node does, instead of exposing a namespace with uninitialized bindings (#16389)
  • [jest-runtime] Strip the byte-order mark when importing a JSON module, matching require() and Node (#16389)
  • [jest-runtime] Throw ERR_REQUIRE_ASYNC_MODULE when require(esm) runs under an async-only custom resolver, instead of silently resolving with the default resolver (#16389)
  • [jest-runtime] Parse imported JSON modules with the test realm's JSON, so their objects pass instanceof Object inside the test like require()d JSON does (#16389)
  • [jest-runtime] Accept every file: URL string in the sandboxed module.createRequire, including one with a localhost authority, as Node does (#16389)
  • [jest-runtime] Point at {virtual: true} when jest.mock or jest.unstable_mockModule is given a module that cannot be resolved (#16389)
  • [jest-reporters] Fix coverage report table formatting in CI/GitHub Actions environments where process.stdout.columns is undefined by falling back to the COLUMNS env var or 80 columns in CI, preserving existing behaviour in other non-TTY environments (#16227)
  • [jest-runtime] Support CJS-in-ESM exports via "module.exports" named exports (#16277)
  • [jest-snapshot] Keep a skipped or failed test's hinted snapshots, instead of reporting them obsolete (#16348)
  • [jest-util] Stop globsToMatcher reusing a cached matcher compiled with different picomatch options, and keep its dot: true default when dot is passed as undefined (#16381)
  • [pretty-format] Move the react-is aliases into the @jest scope, so they cannot be shadowed by unrelated packages published under the alias names (#16333)

Chore & Maintenance

  • [docs] Document the intentional divergences from Node's module system in the ECMAScript Modules page (#16368)
  • [docs] Note deprecation of react-test-renderer in React Native tutorial and pretty-format README (#16294)
  • [docs] Use @testing-library/react-native in the React Native tutorial instead of the deprecated react-test-renderer (#16318)
  • [babel-jest, @jest/transform] Update babel-plugin-istanbul to v8 (#16049)
  • [jest-config, @jest/reporters, jest-runtime] Update glob to v13 (#16397)
  • [jest-haste-map] Refactor massive class into multiple files (#16180)
  • [jest-haste-map] Drop walker dependency; replace hand-rolled directory recursion in the JS crawler and watcher startup with fdir (#16187)
  • [jest-haste-map] Reuse cached metadata for files whose haste name is a known duplicate, instead of re-reading and re-parsing them on every startup (#16351)
  • [jest-haste-map] Cache the watchman socket path and replace the watchman --version probe with get-sockname, so warm runs spawn no watchman processes (#16386)
  • [jest-resolve] Store the per-directory package-type lookup in the cache it reads, so it actually memoizes (#16369)
  • [jest-resolve, jest-runtime] Cut repeated work on the resolution hot path: hoist the platform-extension list to construction, memoize isCoreModule and the options cache-key serialization, skip mapper preparation when no moduleNameMapper is configured, run each mapper regex once, and stop re-parsing NODE_OPTIONS on every default-resolver call (#16371)
  • [jest-resolve] Cut warm resolution cost to about a third: reuse one unrs-resolver factory per options shape instead of cloning per resolution, compose the factory cache key from per-array cached strings instead of serializing options, and stop constructing an Error for misses that findNodeModule swallows; add a __benchmarks__ suite for the default resolver (#16373)
  • [jest-runner, @jest/source-map] Replace source-map-support with an implementation in @jest/source-map (#16327)
  • [jest-snapshot] Load babel, semver and synckit lazily, so requiring the package (which every test process does through @jest/expect) no longer loads ~200 modules that only writing inline snapshots needs (#16387)
  • [jest-runtime] Reduce per-require overhead: skip module ID resolution when no mock can apply, answer core modules before probing for a manual mock, share one require.cache proxy across modules, and cache empty files (#16376)
  • [@jest/source-map] Deprecate getCallsite in favour of SourceMapSupport#getCallsite (#16327)
  • [jest-runtime] Avoid magical null value in ESM loader (#16160)

New Contributors

Full Changelog: v30.4.2...v30.5.0

30.4.1

Features

  • [jest-config, jest-core, jest-runner, jest-schemas, jest-types] Allow custom runner configuration options via tuple format ['runner-path', {options}] (#16141)

Fixes

  • [jest-runtime] Align CJS-from-ESM default export with Node: module.exports is always the ESM default, __esModule unwrapping is no longer applied (#16143)

Full Changelog: v30.4.0...v30.4.1

30.4.0

Big release! 😀

Main feature is a rewrite of our custom runtime in preparation for stabilisation of native support of ESM. As part of that work require(esm) module is now supported on Node 24.9+ (still requires --experimental-vm-modules like before).

In addition we now support fake timers for the recently released Temporal API in Node v26.

React 19 is also supported properly in pretty-format, meaning snapshots of React components now work like they should.

Due to all the changes, there might be regressions that snuck in. Please report them!

Full list of changes below

Features

  • [babel-jest] Support collecting coverage from .mts, .cts (and other) files (#15994)
  • [jest-circus, jest-cli, jest-config, jest-core, jest-jasmine2, jest-types] Add --collect-tests flag to discover and list tests without executing them (#16006)
  • [jest-config, jest-runner, jest-worker] Add workerGracefulExitTimeout config option to control how long workers are given to exit before being force-killed (#15984)
  • [jest-config] Add support for jest.config.mts as a valid configuration file (#16005)
  • [jest-config, jest-core, jest-reporters, jest-runner] verbose and silent can now be set per-project; the project-level value overrides the global value for that project's tests (#16133)
  • [@jest/fake-timers] Accept Temporal.Duration in jest.advanceTimersByTime() and jest.advanceTimersByTimeAsync() (#16128)
  • [@jest/fake-timers] Accept Temporal.Instant and Temporal.ZonedDateTime in jest.setSystemTime() and useFakeTimers({now}) (#16128)
  • [@jest/fake-timers] Support faking Temporal.Now.* (#16131)
  • [jest-mock] Add clearMocksOnScope(scope) on ModuleMocker for clearing every mock function exposed on a scope object (#16088)
  • [jest-resolve] Add canResolveSync() on Resolver so callers can detect when a user-configured resolver only exports an async hook (#16064)
  • [jest-runtime] Use synchronous evaluate() for ES modules without top-level await on Node versions that support it (v24.9+), and prefer the synchronous transform path when a sync transformer is configured (#16062)
  • [jest-runtime] Support require() of ES modules on Node v24.9+ (#16074)
  • [jest-runtime] Validate TC39 import attributes (with { type: 'json' }) on ESM imports (#16127)
  • [@jest/transform] Add canTransformSync(filename) on ScriptTransformer so callers can pick the sync vs async transform path (#16062)
  • [jest-util] Add isError helper (#16076)
  • [pretty-format] Support React 19 (#16123)

Fixes

  • [expect-utils] Fix toStrictEqual failing on structuredClone results due to cross-realm constructor mismatch (#15959)
  • [@jest/expect-utils] Prevent toMatchObject/subset matching from throwing when encountering exotic iterables (#15952)
  • [fake-timers] Convert Date to milliseconds before passing to @sinonjs/fake-timers (#16029)
  • [jest] Export GlobalConfig and ProjectConfig TypeScript types (#16132)
  • [jest-circus] Prevent crash when asyncError is undefined for non-Error throws (#16003)
  • [jest-circus, jest-jasmine2] Include Error.cause in JSON failureMessages output (#15967)
  • [jest-config] Fix preset path resolution on Windows when the preset uses subpath exports (#15961)
  • [jest-config] Allow collectCoverage and coverageProvider in project config without a validation warning (#16132)
  • [jest-config] Project config validator now emits "is not supported in an individual project configuration" instead of "probably a typing mistake" for known global-only options (#16132)
  • [jest-environment-node] Fix --localstorage-file warning on Node 25+ (#16086)
  • [jest-reporters] Apply global coverage threshold to unmatched pattern files in addition to glob/path thresholds (#16137)
  • [jest-reporters, jest-runner, jest-runtime, jest-transform] Fix coverage report not showing correct code coverage when using projects config option (#16140)
  • [jest-runtime] Resolve expect and @jest/expect from the internal module registry so test-file imports share the same JestAssertionError as the global expect (#16130)
  • [jest-runtime] Improve CJS-from-ESM interop: __esModule/Babel default unwrap, broader named-export coverage, and shared CJS singleton across importers (#16050)
  • [jest-runtime] Load .js files with ESM syntax but no "type":"module" marker as native ESM (#16050)
  • [jest-runtime] Extend the .js-with-ESM-syntax fallback to require() on Node v24.9+ - falls back to require(esm) when the CJS parser rejects ESM syntax (#16078)
  • [jest-runtime] Fix deadlocks and double-evaluation in concurrent ESM and wasm imports (#16050)
  • [jest-runtime] Fix error when require() is called after the Jest environment has been torn down (#15951)
  • [jest-runtime] Fix missing error when import() is called after the Jest environment has been torn down (#16080)
  • [jest-runtime] Fix virtual unstable_mockModule registrations not respected in ESM (#16081)
  • [jest-runtime] Apply moduleNameMapper when resolving modules with require.resolve() and the paths option (#16135)

Chore & Maintenance

  • [@jest/fake-timers] Upgrade @sinonjs/fake-timers (#16139)
  • [jest-runtime] Use synchronous linkRequests / instantiate for ESM linking on Node v24.9+ (#16063)

New Contributors

Full Changelog: v30.3.0...v30.4.0

30.3.0

Features

  • [jest-config] Add defineConfig and mergeConfig helpers for type-safe Jest config (#15844)
  • [jest-fake-timers] Add setTimerTickMode to configure how timers advance
  • [*] Reduce token usage when run through LLMs (3f17932)

Fixes

  • [jest-config] Keep CLI coverage output when using --json with --outputFile (#15918)
  • [jest-mock] Use Symbol from test environment (#15858)
  • [jest-reporters] Fix issue where console output not displayed for GHA reporter even with silent: false option (#15864)
  • [jest-runtime] Fix issue where user cannot utilize dynamic import despite specifying --experimental-vm-modules Node option (#15842)
  • [jest-test-sequencer] Fix issue where failed tests due to compilation errors not getting re-executed even with --onlyFailures CLI option (#15851)
  • [jest-util] Make sure process.features.require_module is false (#15867)

Chore & Maintenance

  • [*] Replace remaining micromatch uses with picomatch
  • [deps] Update to sinon/fake-timers v15
  • [docs] Update V30 migration guide to notify users on jest.mock() work with case-sensitive path (#15849)
  • Updated Twitter icon to match the latest brand guidelines (#15869)

30.2.0

Chore & Maintenance

  • [*] Update example repo for testing React Native projects (#15832)
  • [*] Update jest-watch-typeahead to v3 (#15830)

Features

  • [jest-environment-jsdom-abstract] Add support for JSDOM v27 (#15834)

Fixes

  • [babel-jest] Export the TransformerConfig interface (#15820)
  • [jest-config] Fix jest.config.ts with TS loader specified in docblock pragma (#15839)

30.1.1

Fixes

  • [jest-snapshot-utils] Fix deprecated goo.gl snapshot warning not handling Windows end-of-line sequences (#15800)

30.1.0

Features

  • [jest-leak-detector] Configurable GC aggressiveness regarding to V8 heap snapshot generation (#15793)
  • [jest-runtime] Reduce redundant ReferenceError messages
  • [jest-core] Include test modules that failed to load when --onlyFailures is active

Fixes

  • `[jest-snapshot-utils] Fix deprecated goo.gl snapshot guide link not getting replaced with fully canonical URL (#15787)
  • [jest-circus] Fix it.concurrent not working with describe.skip (#15765)
  • [jest-snapshot] Fix mangled inline snapshot updates when used with Prettier 3 and CRLF line endings
  • [jest-runtime] Importing from @jest/globals in more than one file no longer breaks relative paths (#15772)

Chore

  • [expect] Update docblock for toContain() to display info on substring check (#15789)

30.0.5 (from changelog)

Features

  • [jest-config] Allow testMatch to take a string value
  • [jest-worker] Let workerIdleMemoryLimit accept 0 to always restart worker child processes

Fixes

  • [expect] Fix bigint error (#15702)

30.0.4 (from changelog)

Features

  • [expect] The Inverse type is now exported (#15714)
  • [expect] feat: support async functions in toBe (#15704)

Fixes

  • [jest] jest --onlyFailures --listTests now correctly lists only failed tests (#15700)
  • [jest-snapshot] Handle line endings in snapshots (#15708)

30.0.2

What's Changed

Fixes

  • [jest-matcher-utils] Make 'deepCyclicCopyObject' safer by setting descriptors to a null-prototype object (#15689)
  • [jest-util] Make garbage collection protection property writable (#15689)

Full Changelog: https://github.com/jestjs/jest/blob/main/CHANGELOG.md

30.0.1

What's Changed

Features

  • [jest-resolver] Implement the defaultAsyncResolver (#15679)

Fixes

  • [jest-resolver] Resolve builtin modules correctly (#15683)
  • [jest-environment-node, jest-util] Avoid setting globals cleanup protection symbol when feature is off (#15684)

Chore & Maintenance

  • [*] Remove and deprecate jest-repl package (#15673)
  • [jest-resolver] Replace custom isBuiltinModule with node's isBuiltin (#15685)

New Contributors

Full Changelog: https://github.com/jestjs/jest/blob/main/CHANGELOG.md

30.0.0

Today we are happy to announce the release of Jest 30. This release features a substantial number of changes, fixes, and improvements. While it is one of the largest major releases of Jest ever, we admit that three years for a major release is too long. In the future, we are aiming to make more frequent major releases to keep Jest great for the next decade.

If you want to skip all the news and just get going, run npm install jest@^30.0.0 and follow the migration guide: Upgrading from Jest 29 to 30.

Read the full blog post

Features

  • [*] Renamed globalsCleanupMode to globalsCleanup and --waitNextEventLoopTurnForUnhandledRejectionEvents to --waitForUnhandledRejections
  • [expect] Add ArrayOf asymmetric matcher for validating array elements. (#15567)
  • [babel-jest] Add option excludeJestPreset to allow opting out of babel-preset-jest (#15164)
  • [expect] Revert #15038 to fix expect(fn).toHaveBeenCalledWith(expect.objectContaining(...)) when there are multiple calls (#15508)
  • [jest-circus, jest-cli, jest-config] Add waitNextEventLoopTurnForUnhandledRejectionEvents flag to minimise performance impact of correct detection of unhandled promise rejections introduced in #14315 (#14681)
  • [jest-circus] Add a waitBeforeRetry option to jest.retryTimes (#14738)
  • [jest-circus] Add a retryImmediately option to jest.retryTimes (#14696)
  • [jest-circus, jest-jasmine2] Allow setupFilesAfterEnv to export an async function (#10962)
  • [jest-circus, jest-test-result] Add startedAt timestamp in TestCaseResultObject within onTestCaseResult (#15145)
  • [jest-cli] Export buildArgv (#15310)
  • [jest-config] [BREAKING] Add mts and cts to default moduleFileExtensions config (#14369)
  • [jest-config] [BREAKING] Update testMatch and testRegex default option for supporting mjs, cjs, mts, and cts (#14584)
  • [jest-config] Loads config file from provided path in package.json (#14044)
  • [jest-config] Allow loading jest.config.cts files (#14070)
  • [jest-config] Show rootDir in error message when a preset fails to load (#15194)
  • [jest-config] Support loading TS config files using esbuild-register via docblock loader (#15190)
  • [jest-config] Allow passing TS config loader options via docblock comment (#15234)
  • [jest-config] If Node is running with type stripping enabled, do not require a TS loader (#15480)
  • [@jest/core] Group together open handles with the same stack trace (#13417, & #14789)
  • [@jest/core] Add perfStats to surface test setup overhead (#14622)
  • [@jest/core] [BREAKING] Changed --filter to accept an object with shape { filtered: Array<string> } to match documentation (#13319)
  • [@jest/core] Support --outputFile option for --listTests (#14980)
  • [@jest/core] Stringify Errors properly with --json flag (#15329)
  • [@jest/core, @jest/test-sequencer] [BREAKING] Exposes globalConfig & contexts to TestSequencer (#14535, & #14543)
  • [jest-each] Introduce %$ option to add number of the test to its title (#14710)
  • [@jest/environment] [BREAKING] Remove deprecated jest.genMockFromModule() (#15042)
  • [@jest/environment] [BREAKING] Remove unnecessary defensive code (#15045)
  • [jest-environment-jsdom] [BREAKING] Upgrade JSDOM to v22 (#13825)
  • [@jest/environment-jsdom-abstract] Introduce new package which abstracts over the jsdom environment, allowing usage of custom versions of JSDOM (#14717)
  • [jest-environment-node] Update jest environment with dispose symbols Symbol (#14888 & #14909)
  • [expect, @jest/expect] [BREAKING] Add type inference for function parameters in CalledWith assertions (#15129)
  • [@jest/expect-utils] Properly compare all types of TypedArrays (#15178)
  • [@jest/fake-timers] [BREAKING] Upgrade @sinonjs/fake-timers to v13 (#14544 & #15470)
  • [@jest/fake-timers] Exposing new modern timers function advanceTimersToFrame() which advances all timers by the needed milliseconds to execute callbacks currently scheduled with requestAnimationFrame (#14598)
  • [jest-matcher-utils] Add SERIALIZABLE_PROPERTIES to allow custom serialization of objects (#14893)
  • [jest-mock] Add support for the Explicit Resource Management proposal to use the using keyword with jest.spyOn(object, methodName) (#14895)
  • [jest-reporters] Add support for DEC mode 2026 (#15008)
  • [jest-resolver] Support file:// URLs as paths (#15154)
  • [jest-resolve,jest-runtime,jest-resolve-dependencies] Pass the conditions when resolving stub modules (#15489)
  • [jest-runtime] Exposing new modern timers function jest.advanceTimersToFrame() from @jest/fake-timers (#14598)
  • [jest-runtime] Support import.meta.filename and import.meta.dirname (available from Node 20.11) (#14854)
  • [jest-runtime] Support import.meta.resolve (#14930)
  • [jest-runtime] [BREAKING] Make it mandatory to pass globalConfig to the Runtime constructor (#15044)
  • [jest-runtime] Add unstable_unmockModule (#15080)
  • [jest-runtime] Add onGenerateMock transformer callback for auto generated callbacks (#15433 & #15482)
  • [jest-runtime] [BREAKING] Use vm.compileFunction over vm.Script (#15461)
  • [@jest/schemas] Upgrade @sinclair/typebox to v0.34 (#15450)
  • [@jest/types] test.each(): Accept a readonly (as const) table properly (#14565)
  • [@jest/types] Improve argument type inference passed to test and describe callback functions from each tables (#14920)
  • [jest-snapshot] [BREAKING] Add support for Error causes in snapshots (#13965)
  • [jest-snapshot] Support Prettier 3 (#14566)
  • [@jest/util-snapshot] Extract utils used by tooling from jest-snapshot into its own package (#15095)
  • [pretty-format] [BREAKING] Do not render empty string children ('') in React plugin (#14470)

Fixes

  • [expect] Show AggregateError to display (#15346)
  • [*] Replace exit with exit-x (#15399)
  • [babel-plugin-jest-hoist] Use denylist instead of the deprecated blacklist for Babel 8 support (#14109)
  • [babel-plugin-jest-hoist] Do not rely on buggy Babel behaviour (#15415)
  • [expect] Check error instance type for toThrow/toThrowError (#14576)
  • [expect] Improve diff for failing expect.objectContaining (#15038)
  • [expect] Use Array.isArray to check if an array is an Array (#15101)
  • [expect] Fix Error cause assertion errors (#15339)
  • [jest-changed-files] Print underlying errors when VCS commands fail (#15052)
  • [jest-changed-files] Abort sl root call if output resembles a steam locomotive (#15053)
  • [jest-circus] [BREAKING] Prevent false test failures caused by promise rejections handled asynchronously (#14315)
  • [jest-circus] Replace recursive makeTestResults implementation with iterative one (#14760)
  • [jest-circus] Omit expect.hasAssertions() errors if a test already has errors (#14866)
  • [jest-circus, jest-expect, jest-snapshot] Pass test.failing tests when containing failing snapshot matchers (#14313)
  • [jest-circus] Concurrent tests now emit jest circus events at the correct point and in the expected order. (#15381)
  • [jest-cli] [BREAKING] Validate CLI flags that require arguments receives them (#14783)
  • [jest-config] Make sure to respect runInBand option (#14578)
  • [jest-config] Support testTimeout in project config (#14697)
  • [jest-config] Support coverageReporters in project config (#14697)
  • [jest-config] Allow reporters in project config (#14768)
  • [jest-config] Allow Node16/NodeNext/Bundler moduleResolution in project's tsconfig (#14739)
  • [@jest/create-cache-key-function] Correct the return type of createCacheKey (#15159)
  • [jest-each] Allow $keypath templates with null or undefined values (#14831)
  • [@jest/expect-utils] Fix comparison of DataView (#14408)
  • [@jest/expect-utils] [BREAKING] exclude non-enumerable in object matching (#14670)
  • [@jest/expect-utils] Fix comparison of URL (#14672)
  • [@jest/expect-utils] Check Symbol properties in equality (#14688)
  • [@jest/expect-utils] Catch circular references within arrays when matching objects (#14894)
  • [@jest/expect-utils] Fix not addressing to Sets and Maps as objects without keys (#14873)
  • [jest-haste-map] Fix errors or clobbering with multiple hasteImplModulePaths (#15522)
  • [jest-leak-detector] Make leak-detector more aggressive when running GC (#14526)
  • [jest-runtime] Properly handle re-exported native modules in ESM via CJS (#14589)
  • [jest-runtime] Refactor _importCoreModel so required core module is consistent if modified while loading (#15077)
  • [jest-schemas, jest-types] [BREAKING] Fix type of testFailureExitCode config option(#15232)
  • [jest-util] Make sure isInteractive works in a browser (#14552)
  • [pretty-format] [BREAKING] Print ArrayBuffer and DataView correctly (#14290)
  • [pretty-format] Fixed a bug where "anonymous custom elements" were not being printed as expected. (#15138)
  • [jest-cli] When specifying paths on the command line, only match against the relative paths of the test files (#12519)
    • [BREAKING] Changes testPathPattern configuration option to testPathPatterns, which now takes a list of patterns instead of the regex.
    • [BREAKING] --testPathPattern is now --testPathPatterns
    • [BREAKING] Specifying testPathPatterns when programmatically calling watch must be specified as new TestPathPatterns(patterns), where TestPathPatterns can be imported from @jest/pattern
  • [jest-reporters, jest-runner] Unhandled errors without stack get correctly logged to console (#14619)
  • [jest-util] Always load mjs files with import (#15447)
  • [jest-worker] Properly handle a circular reference error when worker tries to send an assertion fails where either the expected or actual value is circular (#15191)
  • [jest-worker] Properly handle a BigInt when worker tries to send an assertion fails where either the expected or actual value is BigInt (#15191)
  • [expect] Resolve issue where ObjectContaining matched non-object values. ([#15463])(#15463).
    • Adds a conditional/check to ensure the argument passed to expect is an object.
    • Add unit tests for new ObjectContaining behavior.
    • Remove invalid/wrong test case assertions for ObjectContaining.
  • [jest-worker] Addresses incorrect state on exit (#15610)

Performance

  • [*] [BREAKING] Bundle all of Jest's modules into index.js (#12348, #14550 & #14661)
  • [jest-haste-map] Only spawn one process to check for watchman installation (#14826)
  • [jest-runner] Better cleanup source-map-support after test to resolve (minor) memory leak (#15233)
  • [jest-circus, jest-environment-node, jest-repl, jest-runner, jest-util] Cleanup global variables on environment teardown to reduce memory leaks (#15215 & #15636 & #15643)

Chore & Maintenance

  • [jest-environment-jsdom, jest-environment-jsdom-abstract] Increased version of jsdom to ^26.0.0 (#15325CVE-2024-37890)
  • [*] Increase version of micromatch to ^4.0.7 (#15082)
  • [*] [BREAKING] Drop support for Node.js versions 14, 16, 19, 21 and 23 (#14460, #15118, #15623, #15640)
  • [*] [BREAKING] Drop support for typescript@4.3, minimum version is now 5.4 (#14542, #15621)
  • [*] Depend on exact versions of monorepo dependencies instead of ^ range (#14553)
  • [*] [BREAKING] Add ESM wrapper for all of Jest's modules (#14661)
  • [*] [BREAKING] Upgrade to glob@10 (#14509)
  • [*] Use TypeError over Error where appropriate (#14799)
  • [docs] Fix typos in CHANGELOG.md and packages/jest-validate/README.md (#14640)
  • [docs] Don't use alias matchers in docs (#14631)
  • [babel-jest, babel-preset-jest] [BREAKING] Increase peer dependency of @babel/core to ^7.11 (#14109)
  • [babel-jest, @jest/transform] Update babel-plugin-istanbul to v6 (#15156)
  • [babel-plugin-jest-hoist] Move unnecessary dependencies to devDependencies (#15010)
  • [expect] [BREAKING] Remove .toBeCalled(), .toBeCalledTimes(), .toBeCalledWith(), .lastCalledWith(), .nthCalledWith(), .toReturn(), .toReturnTimes(), .toReturnWith(), .lastReturnedWith(), .nthReturnedWith() and .toThrowError() matcher aliases (#14632)
  • [jest-cli, jest-config, @jest/types] [BREAKING] Remove deprecated --init argument (#14490)
  • [jest-config, @jest/core, jest-util] Upgrade ci-info (#14655)
  • [jest-mock] [BREAKING] Remove MockFunctionMetadataType, MockFunctionMetadata and SpyInstance types (#14621)
  • [@jest/reporters] Upgrade istanbul-lib-source-maps (#14924)
  • [jest-schemas] Upgrade @sinclair/typebox (#14775)
  • [jest-transform] Upgrade write-file-atomic (#14274)
  • [jest-util] Upgrade picomatch to v4 (#14653 & #14885)
  • [docs] Append to NODE_OPTIONS, not overwrite ([#14730](https://github.com/jestjs/jest/pull/14730))
  • [docs] Updated .toHaveBeenCalled() documentation to correctly reflect its functionality (#14842)
  • [docs] Link NestJS documentation on testing with Jest (#14940)
  • [docs] Revised documentation for .toHaveBeenCalled() to accurately depict its functionality. (#14853)
  • [docs] Removed ExpressJS reference link from documentation due to dead link (#15270)
  • [docs] Correct broken links in docs (#15359)

See the CHANGELOG.

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ @​jest/globals (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ @​jest/reporters (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ @​jest/schemas (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

30.5.0

On a personal note: King Harald V of Norway passed away this morning. He ascended the throne 35 years ago, two months before I was born. This release is dedicated to his memory. Hvil i fred 🇳🇴


This is a big release. It touches jest-runtime, jest-resolve and jest-haste-map in many places, and with this many changes there might be regressions 😬. If your suite behaves differently after upgrading, please open an issue.

Highlights

whenCalledWith

Mock functions can now configure return values per argument list, contributed by @timkindberg (#16053):

const fn = jest.fn();
fn.whenCalledWith('apple').mockReturnValue('red');
fn.whenCalledWith('banana').mockReturnValue('yellow');
fn.whenCalledWith(expect.any(Number)).mockReturnValue('numeric');

fn('apple'); // 'red'
fn('banana'); // 'yellow'
fn(42); // 'numeric'
fn('grape'); // undefined

The returned object is a real Mock, so mockReturnValueOnce, mockResolvedValue, mockImplementation etc. all chain here too. Argument slots accept literals or any asymmetric matcher, with the same equality semantics as toHaveBeenCalledWith(). Calls that match nothing fall through to the base mock. See the Mock Functions docs for matching and precedence details.

Describe-level retries

jest.retryTimes() can now retry a whole describe block instead of a single test, contributed by @soltonigiri (#16322). Each attempt reruns the block's beforeAll/afterAll hooks, child tests and nested describes, which helps when tests in a block depend on shared state:

describe('workflow', () => {
  jest.retryTimes(3, {entireDescribe: true});

  test('first step', () => {});
  test('second step', () => {}); // a failure retries the entire block
});

New file watcher

The non-watchman path of jest-haste-map is rewritten. @parcel/watcher replaces the homegrown NodeWatcher and FSEventsWatcher (#16188), and fdir replaces the hand-rolled directory recursion in the crawler (#16187). A batch of fixes also makes watching and indexing survive locked files on Windows, watchman failures, and duplicate manual mocks (#16295, #16358, #16355, #16360).

If you can, please run your suite with --no-watchman (in and out of watch mode) to exercise the new crawler and watchers, and report anything odd 👍

Long-requested dependency updates

  • babel-plugin-istanbul is updated to v8 (#16049)
  • glob is updated to v13 (#16397)
  • source-map-support is replaced with an implementation in @jest/source-map (#16327). This fixes a memory leak where source-map-support's process-global caches pinned every finished test file's sandbox. Source maps also survive environment teardown, --testLocationInResults looks up the right column, and scheme-prefixed sources like webpack:/// are kept as-is.

Performance

  • Warm module resolution costs about a third of what it did, and repeated work is gone from the resolution hot path (#16373, #16371).
  • Per-require overhead in jest-runtime is cut: module ID resolution is skipped when no mock can apply, and core modules answer before the manual-mock probe (#16376).
  • jest-snapshot loads babel, semver and synckit lazily, so every test process loads ~200 fewer modules (#16387).
  • jest-haste-map caches the watchman socket path, so warm runs spawn no watchman processes (#16386), and reuses cached metadata for duplicated haste names instead of re-parsing them on every startup (#16351).

More new APIs

  • Snapshot failures expose the .snap file path as matcherResult.snapshotPath in failureDetails (#16374).
  • --collectTests expands test.each/describe.each cases and reports per-status counts plus a summary line that matches a real run (#16259).
  • AggregateError inner errors and nested cause chains render with code frames and per-level indentation, and are included in --json output, retryReasons and reporter annotations (#16316).

ESM

A long list of fixes brings jest-runtime's module system closer to Node's:

  • Automocking and manual __mocks__ files now apply to ESM on Node 24.9+. Static imports, dynamic import() and require() of an ESM file generate an automock from the real module's namespace instead of failing with "Attempting to import a mock without a factory" (#16391).
  • Many jest.unstable_mockModule gaps are closed: mocks apply when the mocked file is require()d directly, async factories run once and fail the import instead of crashing the worker 😅, and mocks made inside jest.isolateModules stay scoped to that block (#16389, #16365).
  • require(esm), CJS/ESM interop, import.meta, data: URIs and error ordering now match Node in dozens of edge cases. See the Fixes section for the full list (#16364 through #16391).
  • The module-sync export condition resolves, so packages that expose their ESM entry point for require() load the same file Node picks (#16336).

The intentional divergences from Node's module system are now documented on the ECMAScript Modules page (#16368).

Resolver

  • The default resolver honors Node's --preserve-symlinks / NODE_PRESERVE_SYMLINKS (#16260).
  • moduleNameMapper applies to both spellings of core module specifiers (fs and node:fs), and builtins that only exist prefixed (node:sqlite, node:test) resolve asynchronously (#16390, #16388).
  • A user resolver can be written as an ES module (#16332).

On top of the highlights there are ~60 fixes across jest-circus, jest-haste-map, jest-config, jest-mock and the transform cache keys. See the full changelog below 😀


Features

  • [@jest/expect-utils, jest-mock] Add mockFn.whenCalledWith(...args) for configuring return values per argument list, with first-class asymmetric-matcher support (#16053)
  • [@jest/expect-utils] Export AsymmetricMatcher and FunctionParameters types (previously private to expect) (#16053)
  • [jest-circus, jest-core, jest-jasmine2, jest-test-result, jest-types] --collectTests now expands test.each/describe.each cases and reports per-status counts (skipped/todo via the new wouldRun flag for selected tests) plus a summary line that match a real run, including under --testNamePattern and .only/fdescribe focus on both the circus and jasmine2 runners (#16259)
  • [jest-circus, jest-environment, jest-runtime, jest-types] Add describe-level retries via jest.retryTimes(..., {entireDescribe: true}) (#16322)
  • [jest-circus, jest-message-util, jest-reporters, jest-types] Add retryMessages to AssertionResult and export formatErrorStack, so the retry log renders nested cause and AggregateError sections with code frames instead of serialized [cause]:/[errors]: markers (#16316)
  • [jest-circus, jest-types] Add unhandledErrorsDetailed to Circus.RunResult, so an unhandled rejection reports its cause chain and AggregateError entries with code frames instead of a pre-serialized stack (#16316)
  • [jest-haste-map] Replace NodeWatcher and FSEventsWatcher with @parcel/watcher for the non-watchman watch path (#16188)
  • [jest-resolve] Bump unrs-resolver to 1.12.1, remove jest-pnp-resolver and unnecessary checks (#15721)
  • [jest-resolve] Honor Node's --preserve-symlinks / NODE_PRESERVE_SYMLINKS in the default resolver by passing symlinks: false to unrs-resolver (#16260)
  • [jest-runtime] Apply automocking and manual __mocks__ files to synchronously evaluable ESM graphs on Node 24.9+ - static imports, dynamic import() and require() of an ESM file now generate an automock from the real module's namespace instead of failing with "Attempting to import a mock without a factory". Graphs that need async evaluation (top-level await) or an async-only resolver or transformer still throw (#16391)
  • [jest-runtime] Route process.getBuiltinModule through the sandbox, so it returns the sandbox process and the hooked node:module instead of the host's (#16391)
  • [jest-runtime] Throw an actionable error from module.register() and module.registerHooks() inside a test - the hooks attached to the loader running Jest itself, never saw the sandboxed requires they were meant for, and stayed registered for every later test file in the worker (#16391)
  • [jest-runtime] Surface resolution and import-attribute errors in an ESM graph before executing any of its CJS dependencies on Node 24.9+, matching Node's run-nothing-on-a-broken-graph behavior; the legacy loader on older versions keeps its linking-time execution order (#16391)
  • [jest-runtime] Throw ERR_SOURCE_PHASE_NOT_DEFINED with an actionable message for import source and import.source(), instead of failing at instantiation with V8's bare "Source phase import object is not defined" (#16391)
  • [jest-runtime] Emit the JSON-without-import-attribute deprecation warning once per test file instead of once per worker, so it is no longer silently swallowed for every file after the first (#16391)
  • [jest-runtime] Set import.meta.main to true in the test file and false in every module it loads, matching Node 24+ (#16367)
  • [jest-runtime] Resolve the module-sync export condition, so a package that exposes its ESM entry point for require() loads the same file Node would (#16336)
  • [jest-snapshot] Add external snapshot paths to custom reporter failure details (#16374)

Fixes

  • [jest-console, jest-reporters] CustomConsole now buffers console output so TestResult.console is populated for reporters when verbose is enabled, while GitHubActionsReporter avoids replaying buffered output in verbose mode (#16155)
  • [expect, jest-message-util, jest-pattern, jest-regex-util, jest-util] Revert node: protocol imports to restore webpack/browser-bundle compatibility (#16167)
  • [expect] Widen toMatchObject and objectContaining parameter type from Record<string, unknown> to object so class instances are accepted (#16196)
  • [jest-circus] Call a generator test body with the shared test context, so this matches what a regular test function receives (#16347)
  • [jest-circus] Capture the error listeners of the parent process instead of the in-sandbox process, so listeners registered before the test file survive teardown and sandbox listeners no longer leak onto the parent (#16347)
  • [jest-circus] Clear currentlyRunningTest after skipped and todo tests (#16342)
  • [jest-circus] Prevent late done() callbacks from affecting later test or hook invocations (#16343)
  • [jest-circus, jest-jasmine2] Honor --expand when formatting node:assert failures, instead of always collapsing the diff (#16347)
  • [jest-circus, jest-jasmine2, jest-message-util] Serialize the inner errors of an AggregateError into failureMessages, retryReasons and unhandledErrors, so --json output and reporter annotations include them (#16316)
  • [jest-circus, jest-snapshot] Keep snapshot state and counts correct when a test retries (#16344)
  • [@jest/create-cache-key-function] Include the caller support flags in the generated key, so a transformer that emits ESM or CJS based on them no longer shares one cache entry between the two (#16331)
  • [@jest/create-cache-key-function] Include the stringified project config in the generated key, so editing a transformer's own settings invalidates what it cached (#16331)
  • [@jest/transform] Include the caller support flags in a transform's cache key, so a file transformed both as ESM and as CJS no longer serves one shape's output for the other (#16331)
  • [jest-config] Add missing findRelatedTests, outputFile, and replname entries to ValidConfig so they no longer trigger spurious "Unknown option" warnings (#16224)
  • [jest-config] Use --config for the global config when multiple --projects are specified (#16273)
  • [jest-core] Serialize bigint values in --json and --outputFile output as their literal form (4n), instead of failing the run with TypeError: Do not know how to serialize a BigInt (#16338)
  • [jest-core] Do not report a CustomGC async resource (used by N-API addons such as napi-rs for per-isolate GC bookkeeping) as an open handle, since it is napi_unref'd by the addon and can never keep the event loop alive (#16379)
  • [jest-each] Keep a $&, $`, $' or $$ inside a %p param value out of the replacement, so the title shows the value instead of the text around it (#16338)
  • [jest-each] Interpolate a bigint into a %j title as its literal form ("4n") at any depth, instead of throwing TypeError: Do not know how to serialize a BigInt while collecting the tests (#16338)
  • [jest-environment, jest-runtime] Bind sandboxInjectedGlobals to the right values when injectGlobals is false, instead of shifting every one of them by a position (#16377)
  • [jest-environment-node, jest-util] Only warn about a conflicting globalsCleanup mode when one was explicitly configured, and follow the mode that is actually in effect (#16323)
  • [jest-environment-node, jest-util] Stop resolving lazy globals when setting up an environment, so Node 26's builtin module globals are no longer loaded (and no longer emit their deprecation warnings) for every test file (#16324)
  • [jest-haste-map] Keep watch mode alive when an outside process briefly makes a file unreadable on Windows, instead of tearing the watcher down on EPERM (#16295)
  • [jest-haste-map] Keep indexing when an outside process holds a file open on Windows, instead of failing the whole crawl on EPERM (#16358)
  • [jest-haste-map] Keep a duplicated manual mock resolving when the file it pointed at is deleted in watch mode (#16360)
  • [jest-haste-map] Shut the worker farm down when a duplicate manual mock aborts the build under throwOnModuleCollision (#16354)
  • [jest-haste-map] Attach the watchman client's error listener before the first command, so a watchman failure falls back to the node crawler instead of crashing on an unhandled error event, and always end the client (#16355)
  • [jest-haste-map] Stop delivering watch events after WatchmanWatcher is closed, and route its warnings through the configured console (#16355)
  • [jest-haste-map] Restore the nested duplicates index correctly in ModuleMap.fromJSON, so a haste collision reported inside a test worker raises DuplicateHasteCandidatesError instead of a TypeError (#16353)
  • [jest-haste-map] Match watched files on a full extension, so moduleFileExtensions: ['js'] no longer accepts foo.mjs (#16352)
  • [jest-haste-map] Delimit the fields that make up the haste map cache key, so two different option sets cannot hash to the same cache file (#16352)
  • [jest-message-util] Print the inner errors of an AggregateError thrown inside a test (#16316)
  • [jest-message-util] Indent nested cause and AggregateError sections of a test failure by one level per depth, so the nesting is legible instead of rendering flat (#16316)
  • [jest-message-util] Color stack traces line by line so blank lines stay blank (#16316)
  • [jest-message-util] Detect Jest's own frames without assuming the checkout directory's name, and cover @jest/* packages, so stack traces and code frames point at user code (#16326)
  • [jest-mock] mockResolvedValue / mockRejectedValue now see all overload return types, so a Promise-returning overload survives even when a later overload returns a non-Promise (e.g. pg.Client['end']) (#16237)
  • [@jest-environment/jsdom-abstract] Make @types/jsdom a peer dependency (#16166)
  • [jest-mock] Remove the leftover own accessor descriptor when restoring a spyOn of an inherited getter or setter, so the instance keeps reflecting the prototype (#16226)
  • [jest-resolve] Include extensionsToTreatAsEsm in the shouldLoadAsEsm cache key, so projects with different extension lists don't read each other's answers (#16369)
  • [jest-resolve] Make getModuleIDAsync build and cache data: URI module IDs the same way as getModuleID (#16370)
  • [jest-resolve] Keep the node: prefix when resolving a core module asynchronously, so a builtin that only exists prefixed (node:sea, node:sqlite, node:test, node:test/reporters) resolves instead of failing as a missing bare package (#16388)
  • [jest-resolve] Look up manual mocks for node: protocol specifiers under the unprefixed name they are stored as (#16388)
  • [jest-resolve] Apply moduleNameMapper consistently to both spellings of core module specifiers (fs vs node:fs) (#16390)
  • [jest-resolve] Keep virtual and ordinary mock module IDs isolated across test files (#16296)
  • [jest-resolve] Guard missing require.resolve.paths (#16052)
  • [jest-resolve, jest-config, jest-runner] Support a user resolver written as an ES module (#16332)
  • [jest-resolve, jest-runtime] Throw the CJS parse error for ESM syntax in a "type": "commonjs" package or a .cjs file instead of loading it as ESM, matching Node (#16368)
  • [@jest/source-map] Keep source map sources that name a scheme, such as webpack:///, instead of resolving them into a path that does not exist (#16327)
  • [@jest/source-map] Look up --testLocationInResults positions at the right column, and keep a mapping to the first column instead of discarding it (#16327)
  • [@jest/source-map] Warn when a source map cannot be parsed, instead of silently leaving its frames untranslated (#16327)
  • [jest-runner, @jest/source-map] Keep a source-mapped stack for an error thrown after the test environment was torn down (#16327)
  • [jest-runtime, @jest/source-map] Keep source maps past teardown and past the next test file's install, so a stack from a file no earlier stack mentioned still points at the original source (#16330)
  • [jest-runtime] Report that no coverage was collected when getAllV8CoverageInfoCopy is called after teardown, instead of returning an empty result (#16385)
  • [jest-runtime] Cache a CJS module's parsed exports before walking its re-exports, so two modules that re-export each other no longer overflow the stack when imported from ESM (#16363)
  • [jest-runtime] Keep a re-exported ES module's parse failure from marking the re-exporting CommonJS file as ESM, so module.exports = require('./dep.mjs') loads instead of failing with module is not defined (#16363)
  • [jest-runtime] Scope module mocks instantiated inside jest.isolateModules/isolateModulesAsync to that block, so a mock first imported there no longer outlives it - matching how CommonJS mocks already behave (#16365)
  • [jest-runtime] Suspend module isolation while generating an automock, so loading the real module to read its shape no longer populates the isolated registry (#16365)
  • [jest-runtime] Check a cached ES module's status before require() returns it, so a module whose evaluation threw rethrows that error and one left linked by a failed sibling is evaluated instead of returning uninitialized bindings (#16364)
  • [jest-runtime] Report the original ERR_REQUIRE_ASYNC_MODULE when a require() of a top-level-await graph is retried, instead of a spurious "concurrent import()" error (#16364)
  • [jest-runtime] Throw the evaluation error when another caller's import() of the same module failed while we awaited it, instead of resolving with the errored module (#16364)
  • [jest-runtime] Mark the result of require()ing an ES module that has a default export with __esModule: true through a live-binding facade, and serve the same object from require.cache, matching Node (#16367)
  • [jest-runtime] Provide a CommonJS module's exports under the 'module.exports' named export when imported from ESM, matching Node 23+ (#16367)
  • [jest-runtime] Give the test file itself a non-null require.main (#16367)
  • [jest-runtime] Populate module.children with the modules a file loads, matching Node (#16368)
  • [jest-runtime] Provide import.meta.resolve and import.meta.jest in data: URI modules, accept any-case mediatype parameters, and use Node's error codes for invalid data: URIs (#16368)
  • [jest-runtime] Key ES modules by full URL, so query and fragment suffixes create the same module instances as Node and show up in import.meta.url (#16375)
  • [jest-runtime] Share modules between overlapping graphs when a CommonJS module require()s an ES module mid-load, instead of evaluating shared dependencies twice (#16375)
  • [jest-runtime] Throw ERR_REQUIRE_CYCLE_MODULE like Node when a CommonJS module require()s an ES module that is still being loaded, instead of evaluating the module a second time (#16366)
  • [jest-runtime] Key builtin modules in the ESM registry by one canonical specifier (#16341)
  • [jest-runtime] import.meta.resolve() for a builtin uses its node: specifier (#16341)
  • [jest-runtime] Fall back to native ESM when a .js file contains ESM syntax but has no "type":"module" marker (#16152)
  • [jest-runtime] Allow require() of ESM-marked files on Node < 24.9 via transform fallback (#16244)
  • [jest-runtime, @jest/transform] Surface actionable ERR_REQUIRE_ESM error for files with untransformed ESM syntax instead of the generic "unexpected token" message (#16244)
  • [jest-runtime] Support older test environments whose moduleMocker does not implement clearMocksOnScope (#16169)
  • [jest-runtime] Apply jest.unstable_mockModule when the mocked file itself is require()d, not only when it is imported as a dependency (#16389)
  • [jest-runtime] Apply jest.unstable_mockModule to statically imported data: URIs on Node 24.9+, matching dynamic import() (#16389)
  • [jest-runtime] Run an async jest.unstable_mockModule factory once per module instead of twice, and fail the import instead of crashing the worker when the factory rejects (#16389)
  • [jest-runtime] Hide a require(esm) module that failed to evaluate from require.cache, as Node does, instead of exposing a namespace with uninitialized bindings (#16389)
  • [jest-runtime] Strip the byte-order mark when importing a JSON module, matching require() and Node (#16389)
  • [jest-runtime] Throw ERR_REQUIRE_ASYNC_MODULE when require(esm) runs under an async-only custom resolver, instead of silently resolving with the default resolver (#16389)
  • [jest-runtime] Parse imported JSON modules with the test realm's JSON, so their objects pass instanceof Object inside the test like require()d JSON does (#16389)
  • [jest-runtime] Accept every file: URL string in the sandboxed module.createRequire, including one with a localhost authority, as Node does (#16389)
  • [jest-runtime] Point at {virtual: true} when jest.mock or jest.unstable_mockModule is given a module that cannot be resolved (#16389)
  • [jest-reporters] Fix coverage report table formatting in CI/GitHub Actions environments where process.stdout.columns is undefined by falling back to the COLUMNS env var or 80 columns in CI, preserving existing behaviour in other non-TTY environments (#16227)
  • [jest-runtime] Support CJS-in-ESM exports via "module.exports" named exports (#16277)
  • [jest-snapshot] Keep a skipped or failed test's hinted snapshots, instead of reporting them obsolete (#16348)
  • [jest-util] Stop globsToMatcher reusing a cached matcher compiled with different picomatch options, and keep its dot: true default when dot is passed as undefined (#16381)
  • [pretty-format] Move the react-is aliases into the @jest scope, so they cannot be shadowed by unrelated packages published under the alias names (#16333)

Chore & Maintenance

  • [docs] Document the intentional divergences from Node's module system in the ECMAScript Modules page (#16368)
  • [docs] Note deprecation of react-test-renderer in React Native tutorial and pretty-format README (#16294)
  • [docs] Use @testing-library/react-native in the React Native tutorial instead of the deprecated react-test-renderer (#16318)
  • [babel-jest, @jest/transform] Update babel-plugin-istanbul to v8 (#16049)
  • [jest-config, @jest/reporters, jest-runtime] Update glob to v13 (#16397)
  • [jest-haste-map] Refactor massive class into multiple files (#16180)
  • [jest-haste-map] Drop walker dependency; replace hand-rolled directory recursion in the JS crawler and watcher startup with fdir (#16187)
  • [jest-haste-map] Reuse cached metadata for files whose haste name is a known duplicate, instead of re-reading and re-parsing them on every startup (#16351)
  • [jest-haste-map] Cache the watchman socket path and replace the watchman --version probe with get-sockname, so warm runs spawn no watchman processes (#16386)
  • [jest-resolve] Store the per-directory package-type lookup in the cache it reads, so it actually memoizes (#16369)
  • [jest-resolve, jest-runtime] Cut repeated work on the resolution hot path: hoist the platform-extension list to construction, memoize isCoreModule and the options cache-key serialization, skip mapper preparation when no moduleNameMapper is configured, run each mapper regex once, and stop re-parsing NODE_OPTIONS on every default-resolver call (#16371)
  • [jest-resolve] Cut warm resolution cost to about a third: reuse one unrs-resolver factory per options shape instead of cloning per resolution, compose the factory cache key from per-array cached strings instead of serializing options, and stop constructing an Error for misses that findNodeModule swallows; add a __benchmarks__ suite for the default resolver (#16373)
  • [jest-runner, @jest/source-map] Replace source-map-support with an implementation in @jest/source-map (#16327)
  • [jest-snapshot] Load babel, semver and synckit lazily, so requiring the package (which every test process does through @jest/expect) no longer loads ~200 modules that only writing inline snapshots needs (#16387)
  • [jest-runtime] Reduce per-require overhead: skip module ID resolution when no mock can apply, answer core modules before probing for a manual mock, share one require.cache proxy across modules, and cache empty files (#16376)
  • [@jest/source-map] Deprecate getCallsite in favour of SourceMapSupport#getCallsite (#16327)
  • [jest-runtime] Avoid magical null value in ESM loader (#16160)

New Contributors

Full Changelog: v30.4.2...v30.5.0

30.4.1

Features

  • [jest-config, jest-core, jest-runner, jest-schemas, jest-types] Allow custom runner configuration options via tuple format ['runner-path', {options}] (#16141)

Fixes

  • [jest-runtime] Align CJS-from-ESM default export with Node: module.exports is always the ESM default, __esModule unwrapping is no longer applied (#16143)

Full Changelog: v30.4.0...v30.4.1

30.4.0

Big release! 😀

Main feature is a rewrite of our custom runtime in preparation for stabilisation of native support of ESM. As part of that work require(esm) module is now supported on Node 24.9+ (still requires --experimental-vm-modules like before).

In addition we now support fake timers for the recently released Temporal API in Node v26.

React 19 is also supported properly in pretty-format, meaning snapshots of React components now work like they should.

Due to all the changes, there might be regressions that snuck in. Please report them!

Full list of changes below

Features

  • [babel-jest] Support collecting coverage from .mts, .cts (and other) files (#15994)
  • [jest-circus, jest-cli, jest-config, jest-core, jest-jasmine2, jest-types] Add --collect-tests flag to discover and list tests without executing them (#16006)
  • [jest-config, jest-runner, jest-worker] Add workerGracefulExitTimeout config option to control how long workers are given to exit before being force-killed (#15984)
  • [jest-config] Add support for jest.config.mts as a valid configuration file (#16005)
  • [jest-config, jest-core, jest-reporters, jest-runner] verbose and silent can now be set per-project; the project-level value overrides the global value for that project's tests (#16133)
  • [@jest/fake-timers] Accept Temporal.Duration in jest.advanceTimersByTime() and jest.advanceTimersByTimeAsync() (#16128)
  • [@jest/fake-timers] Accept Temporal.Instant and Temporal.ZonedDateTime in jest.setSystemTime() and useFakeTimers({now}) (#16128)
  • [@jest/fake-timers] Support faking Temporal.Now.* (#16131)
  • [jest-mock] Add clearMocksOnScope(scope) on ModuleMocker for clearing every mock function exposed on a scope object (#16088)
  • [jest-resolve] Add canResolveSync() on Resolver so callers can detect when a user-configured resolver only exports an async hook (#16064)
  • [jest-runtime] Use synchronous evaluate() for ES modules without top-level await on Node versions that support it (v24.9+), and prefer the synchronous transform path when a sync transformer is configured (#16062)
  • [jest-runtime] Support require() of ES modules on Node v24.9+ (#16074)
  • [jest-runtime] Validate TC39 import attributes (with { type: 'json' }) on ESM imports (#16127)
  • [@jest/transform] Add canTransformSync(filename) on ScriptTransformer so callers can pick the sync vs async transform path (#16062)
  • [jest-util] Add isError helper (#16076)
  • [pretty-format] Support React 19 (#16123)

Fixes

  • [expect-utils] Fix toStrictEqual failing on structuredClone results due to cross-realm constructor mismatch (#15959)
  • [@jest/expect-utils] Prevent toMatchObject/subset matching from throwing when encountering exotic iterables (#15952)
  • [fake-timers] Convert Date to milliseconds before passing to @sinonjs/fake-timers (#16029)
  • [jest] Export GlobalConfig and ProjectConfig TypeScript types (#16132)
  • [jest-circus] Prevent crash when asyncError is undefined for non-Error throws (#16003)
  • [jest-circus, jest-jasmine2] Include Error.cause in JSON failureMessages output (#15967)
  • [jest-config] Fix preset path resolution on Windows when the preset uses subpath exports (#15961)
  • [jest-config] Allow collectCoverage and coverageProvider in project config without a validation warning (#16132)
  • [jest-config] Project config validator now emits "is not supported in an individual project configuration" instead of "probably a typing mistake" for known global-only options (#16132)
  • [jest-environment-node] Fix --localstorage-file warning on Node 25+ (#16086)
  • [jest-reporters] Apply global coverage threshold to unmatched pattern files in addition to glob/path thresholds (#16137)
  • [jest-reporters, jest-runner, jest-runtime, jest-transform] Fix coverage report not showing correct code coverage when using projects config option (#16140)
  • [jest-runtime] Resolve expect and @jest/expect from the internal module registry so test-file imports share the same JestAssertionError as the global expect (#16130)
  • [jest-runtime] Improve CJS-from-ESM interop: __esModule/Babel default unwrap, broader named-export coverage, and shared CJS singleton across importers (#16050)
  • [jest-runtime] Load .js files with ESM syntax but no "type":"module" marker as native ESM (#16050)
  • [jest-runtime] Extend the .js-with-ESM-syntax fallback to require() on Node v24.9+ - falls back to require(esm) when the CJS parser rejects ESM syntax (#16078)
  • [jest-runtime] Fix deadlocks and double-evaluation in concurrent ESM and wasm imports (#16050)
  • [jest-runtime] Fix error when require() is called after the Jest environment has been torn down (#15951)
  • [jest-runtime] Fix missing error when import() is called after the Jest environment has been torn down (#16080)
  • [jest-runtime] Fix virtual unstable_mockModule registrations not respected in ESM (#16081)
  • [jest-runtime] Apply moduleNameMapper when resolving modules with require.resolve() and the paths option (#16135)

Chore & Maintenance

  • [@jest/fake-timers] Upgrade @sinonjs/fake-timers (#16139)
  • [jest-runtime] Use synchronous linkRequests / instantiate for ESM linking on Node v24.9+ (#16063)

New Contributors

Full Changelog: v30.3.0...v30.4.0

30.0.5 (from changelog)

Features

  • [jest-config] Allow testMatch to take a string value
  • [jest-worker] Let workerIdleMemoryLimit accept 0 to always restart worker child processes

Fixes

  • [expect] Fix bigint error (#15702)

30.0.1

What's Changed

Features

  • [jest-resolver] Implement the defaultAsyncResolver (#15679)

Fixes

  • [jest-resolver] Resolve builtin modules correctly (#15683)
  • [jest-environment-node, jest-util] Avoid setting globals cleanup protection symbol when feature is off (#15684)

Chore & Maintenance

  • [*] Remove and deprecate jest-repl package (#15673)
  • [jest-resolver] Replace custom isBuiltinModule with node's isBuiltin (#15685)

New Contributors

Full Changelog: https://github.com/jestjs/jest/blob/main/CHANGELOG.md

30.0.0

Today we are happy to announce the release of Jest 30. This release features a substantial number of changes, fixes, and improvements. While it is one of the largest major releases of Jest ever, we admit that three years for a major release is too long. In the future, we are aiming to make more frequent major releases to keep Jest great for the next decade.

If you want to skip all the news and just get going, run npm install jest@^30.0.0 and follow the migration guide: Upgrading from Jest 29 to 30.

Read the full blog post

Features

  • [*] Renamed globalsCleanupMode to globalsCleanup and --waitNextEventLoopTurnForUnhandledRejectionEvents to --waitForUnhandledRejections
  • [expect] Add ArrayOf asymmetric matcher for validating array elements. (#15567)
  • [babel-jest] Add option excludeJestPreset to allow opting out of babel-preset-jest (#15164)
  • [expect] Revert #15038 to fix expect(fn).toHaveBeenCalledWith(expect.objectContaining(...)) when there are multiple calls (#15508)
  • [jest-circus, jest-cli, jest-config] Add waitNextEventLoopTurnForUnhandledRejectionEvents flag to minimise performance impact of correct detection of unhandled promise rejections introduced in #14315 (#14681)
  • [jest-circus] Add a waitBeforeRetry option to jest.retryTimes (#14738)
  • [jest-circus] Add a retryImmediately option to jest.retryTimes (#14696)
  • [jest-circus, jest-jasmine2] Allow setupFilesAfterEnv to export an async function (#10962)
  • [jest-circus, jest-test-result] Add startedAt timestamp in TestCaseResultObject within onTestCaseResult (#15145)
  • [jest-cli] Export buildArgv (#15310)
  • [jest-config] [BREAKING] Add mts and cts to default moduleFileExtensions config (#14369)
  • [jest-config] [BREAKING] Update testMatch and testRegex default option for supporting mjs, cjs, mts, and cts (#14584)
  • [jest-config] Loads config file from provided path in package.json (#14044)
  • [jest-config] Allow loading jest.config.cts files (#14070)
  • [jest-config] Show rootDir in error message when a preset fails to load (#15194)
  • [jest-config] Support loading TS config files using esbuild-register via docblock loader (#15190)
  • [jest-config] Allow passing TS config loader options via docblock comment (#15234)
  • [jest-config] If Node is running with type stripping enabled, do not require a TS loader (#15480)
  • [@jest/core] Group together open handles with the same stack trace (#13417, & #14789)
  • [@jest/core] Add perfStats to surface test setup overhead (#14622)
  • [@jest/core] [BREAKING] Changed --filter to accept an object with shape { filtered: Array<string> } to match documentation (#13319)
  • [@jest/core] Support --outputFile option for --listTests (#14980)
  • [@jest/core] Stringify Errors properly with --json flag (#15329)
  • [@jest/core, @jest/test-sequencer] [BREAKING] Exposes globalConfig & contexts to TestSequencer (#14535, & #14543)
  • [jest-each] Introduce %$ option to add number of the test to its title (#14710)
  • [@jest/environment] [BREAKING] Remove deprecated jest.genMockFromModule() (#15042)
  • [@jest/environment] [BREAKING] Remove unnecessary defensive code (#15045)
  • [jest-environment-jsdom] [BREAKING] Upgrade JSDOM to v22 (#13825)
  • [@jest/environment-jsdom-abstract] Introduce new package which abstracts over the jsdom environment, allowing usage of custom versions of JSDOM (#14717)
  • [jest-environment-node] Update jest environment with dispose symbols Symbol (#14888 & #14909)
  • [expect, @jest/expect] [BREAKING] Add type inference for function parameters in CalledWith assertions (#15129)
  • [@jest/expect-utils] Properly compare all types of TypedArrays (#15178)
  • [@jest/fake-timers] [BREAKING] Upgrade @sinonjs/fake-timers to v13 (#14544 & #15470)
  • [@jest/fake-timers] Exposing new modern timers function advanceTimersToFrame() which advances all timers by the needed milliseconds to execute callbacks currently scheduled with requestAnimationFrame (#14598)
  • [jest-matcher-utils] Add SERIALIZABLE_PROPERTIES to allow custom serialization of objects (#14893)
  • [jest-mock] Add support for the Explicit Resource Management proposal to use the using keyword with jest.spyOn(object, methodName) (#14895)
  • [jest-reporters] Add support for DEC mode 2026 (#15008)
  • [jest-resolver] Support file:// URLs as paths (#15154)
  • [jest-resolve,jest-runtime,jest-resolve-dependencies] Pass the conditions when resolving stub modules (#15489)
  • [jest-runtime] Exposing new modern timers function jest.advanceTimersToFrame() from @jest/fake-timers (#14598)
  • [jest-runtime] Support import.meta.filename and import.meta.dirname (available from Node 20.11) (#14854)
  • [jest-runtime] Support import.meta.resolve (#14930)
  • [jest-runtime] [BREAKING] Make it mandatory to pass globalConfig to the Runtime constructor (#15044)
  • [jest-runtime] Add unstable_unmockModule (#15080)
  • [jest-runtime] Add onGenerateMock transformer callback for auto generated callbacks (#15433 & #15482)
  • [jest-runtime] [BREAKING] Use vm.compileFunction over vm.Script (#15461)
  • [@jest/schemas] Upgrade @sinclair/typebox to v0.34 (#15450)
  • [@jest/types] test.each(): Accept a readonly (as const) table properly (#14565)
  • [@jest/types] Improve argument type inference passed to test and describe callback functions from each tables (#14920)
  • [jest-snapshot] [BREAKING] Add support for Error causes in snapshots (#13965)
  • [jest-snapshot] Support Prettier 3 (#14566)
  • [@jest/util-snapshot] Extract utils used by tooling from jest-snapshot into its own package (#15095)
  • [pretty-format] [BREAKING] Do not render empty string children ('') in React plugin (#14470)

Fixes

  • [expect] Show AggregateError to display (#15346)
  • [*] Replace exit with exit-x (#15399)
  • [babel-plugin-jest-hoist] Use denylist instead of the deprecated blacklist for Babel 8 support (#14109)
  • [babel-plugin-jest-hoist] Do not rely on buggy Babel behaviour (#15415)
  • [expect] Check error instance type for toThrow/toThrowError (#14576)
  • [expect] Improve diff for failing expect.objectContaining (#15038)
  • [expect] Use Array.isArray to check if an array is an Array (#15101)
  • [expect] Fix Error cause assertion errors (#15339)
  • [jest-changed-files] Print underlying errors when VCS commands fail (#15052)
  • [jest-changed-files] Abort sl root call if output resembles a steam locomotive (#15053)
  • [jest-circus] [BREAKING] Prevent false test failures caused by promise rejections handled asynchronously (#14315)
  • [jest-circus] Replace recursive makeTestResults implementation with iterative one (#14760)
  • [jest-circus] Omit expect.hasAssertions() errors if a test already has errors (#14866)
  • [jest-circus, jest-expect, jest-snapshot] Pass test.failing tests when containing failing snapshot matchers (#14313)
  • [jest-circus] Concurrent tests now emit jest circus events at the correct point and in the expected order. (#15381)
  • [jest-cli] [BREAKING] Validate CLI flags that require arguments receives them (#14783)
  • [jest-config] Make sure to respect runInBand option (#14578)
  • [jest-config] Support testTimeout in project config (#14697)
  • [jest-config] Support coverageReporters in project config (#14697)
  • [jest-config] Allow reporters in project config (#14768)
  • [jest-config] Allow Node16/NodeNext/Bundler moduleResolution in project's tsconfig (#14739)
  • [@jest/create-cache-key-function] Correct the return type of createCacheKey (#15159)
  • [jest-each] Allow $keypath templates with null or undefined values (#14831)
  • [@jest/expect-utils] Fix comparison of DataView (#14408)
  • [@jest/expect-utils] [BREAKING] exclude non-enumerable in object matching (#14670)
  • [@jest/expect-utils] Fix comparison of URL (#14672)
  • [@jest/expect-utils] Check Symbol properties in equality (#14688)
  • [@jest/expect-utils] Catch circular references within arrays when matching objects (#14894)
  • [@jest/expect-utils] Fix not addressing to Sets and Maps as objects without keys (#14873)
  • [jest-haste-map] Fix errors or clobbering with multiple hasteImplModulePaths (#15522)
  • [jest-leak-detector] Make leak-detector more aggressive when running GC (#14526)
  • [jest-runtime] Properly handle re-exported native modules in ESM via CJS (#14589)
  • [jest-runtime] Refactor _importCoreModel so required core module is consistent if modified while loading (#15077)
  • [jest-schemas, jest-types] [BREAKING] Fix type of testFailureExitCode config option(#15232)
  • [jest-util] Make sure isInteractive works in a browser (#14552)
  • [pretty-format] [BREAKING] Print ArrayBuffer and DataView correctly (#14290)
  • [pretty-format] Fixed a bug where "anonymous custom elements" were not being printed as expected. (#15138)
  • [jest-cli] When specifying paths on the command line, only match against the relative paths of the test files (#12519)
    • [BREAKING] Changes testPathPattern configuration option to testPathPatterns, which now takes a list of patterns instead of the regex.
    • [BREAKING] --testPathPattern is now --testPathPatterns
    • [BREAKING] Specifying testPathPatterns when programmatically calling watch must be specified as new TestPathPatterns(patterns), where TestPathPatterns can be imported from @jest/pattern
  • [jest-reporters, jest-runner] Unhandled errors without stack get correctly logged to console (#14619)
  • [jest-util] Always load mjs files with import (#15447)
  • [jest-worker] Properly handle a circular reference error when worker tries to send an assertion fails where either the expected or actual value is circular (#15191)
  • [jest-worker] Properly handle a BigInt when worker tries to send an assertion fails where either the expected or actual value is BigInt (#15191)
  • [expect] Resolve issue where ObjectContaining matched non-object values. ([#15463])(#15463).
    • Adds a conditional/check to ensure the argument passed to expect is an object.
    • Add unit tests for new ObjectContaining behavior.
    • Remove invalid/wrong test case assertions for ObjectContaining.
  • [jest-worker] Addresses incorrect state on exit (#15610)

Performance

  • [*] [BREAKING] Bundle all of Jest's modules into index.js (#12348, #14550 & #14661)
  • [jest-haste-map] Only spawn one process to check for watchman installation (#14826)
  • [jest-runner] Better cleanup source-map-support after test to resolve (minor) memory leak (#15233)
  • [jest-circus, jest-environment-node, jest-repl, jest-runner, jest-util] Cleanup global variables on environment teardown to reduce memory leaks (#15215 & #15636 & #15643)

Chore & Maintenance

  • [jest-environment-jsdom, jest-environment-jsdom-abstract] Increased version of jsdom to ^26.0.0 (#15325CVE-2024-37890)
  • [*] Increase version of micromatch to ^4.0.7 (#15082)
  • [*] [BREAKING] Drop support for Node.js versions 14, 16, 19, 21 and 23 (#14460, #15118, #15623, #15640)
  • [*] [BREAKING] Drop support for typescript@4.3, minimum version is now 5.4 (#14542, #15621)
  • [*] Depend on exact versions of monorepo dependencies instead of ^ range (#14553)
  • [*] [BREAKING] Add ESM wrapper for all of Jest's modules (#14661)
  • [*] [BREAKING] Upgrade to glob@10 (#14509)
  • [*] Use TypeError over Error where appropriate (#14799)
  • [docs] Fix typos in CHANGELOG.md and packages/jest-validate/README.md (#14640)
  • [docs] Don't use alias matchers in docs (#14631)
  • [babel-jest, babel-preset-jest] [BREAKING] Increase peer dependency of @babel/core to ^7.11 (#14109)
  • [babel-jest, @jest/transform] Update babel-plugin-istanbul to v6 (#15156)
  • [babel-plugin-jest-hoist] Move unnecessary dependencies to devDependencies (#15010)
  • [expect] [BREAKING] Remove .toBeCalled(), .toBeCalledTimes(), .toBeCalledWith(), .lastCalledWith(), .nthCalledWith(), .toReturn(), .toReturnTimes(), .toReturnWith(), .lastReturnedWith(), .nthReturnedWith() and .toThrowError() matcher aliases (#14632)
  • [jest-cli, jest-config, @jest/types] [BREAKING] Remove deprecated --init argument (#14490)
  • [jest-config, @jest/core, jest-util] Upgrade ci-info (#14655)
  • [jest-mock] [BREAKING] Remove MockFunctionMetadataType, MockFunctionMetadata and SpyInstance types (#14621)
  • [@jest/reporters] Upgrade istanbul-lib-source-maps (#14924)
  • [jest-schemas] Upgrade @sinclair/typebox (#14775)
  • [jest-transform] Upgrade write-file-atomic (#14274)
  • [jest-util] Upgrade picomatch to v4 (#14653 & #14885)
  • [docs] Append to NODE_OPTIONS, not overwrite ([#14730](https://github.com/jestjs/jest/pull/14730))
  • [docs] Updated .toHaveBeenCalled() documentation to correctly reflect its functionality (#14842)
  • [docs] Link NestJS documentation on testing with Jest (#14940)
  • [docs] Revised documentation for .toHaveBeenCalled() to accurately depict its functionality. (#14853)
  • [docs] Removed ExpressJS reference link from documentation due to dead link (#15270)
  • [docs] Correct broken links in docs (#15359)

See the CHANGELOG.

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ @​jest/source-map (indirect, 28.1.2 → 30.5.0) · Repo · Changelog

Release Notes

30.5.0

On a personal note: King Harald V of Norway passed away this morning. He ascended the throne 35 years ago, two months before I was born. This release is dedicated to his memory. Hvil i fred 🇳🇴


This is a big release. It touches jest-runtime, jest-resolve and jest-haste-map in many places, and with this many changes there might be regressions 😬. If your suite behaves differently after upgrading, please open an issue.

Highlights

whenCalledWith

Mock functions can now configure return values per argument list, contributed by @timkindberg (#16053):

const fn = jest.fn();
fn.whenCalledWith('apple').mockReturnValue('red');
fn.whenCalledWith('banana').mockReturnValue('yellow');
fn.whenCalledWith(expect.any(Number)).mockReturnValue('numeric');

fn('apple'); // 'red'
fn('banana'); // 'yellow'
fn(42); // 'numeric'
fn('grape'); // undefined

The returned object is a real Mock, so mockReturnValueOnce, mockResolvedValue, mockImplementation etc. all chain here too. Argument slots accept literals or any asymmetric matcher, with the same equality semantics as toHaveBeenCalledWith(). Calls that match nothing fall through to the base mock. See the Mock Functions docs for matching and precedence details.

Describe-level retries

jest.retryTimes() can now retry a whole describe block instead of a single test, contributed by @soltonigiri (#16322). Each attempt reruns the block's beforeAll/afterAll hooks, child tests and nested describes, which helps when tests in a block depend on shared state:

describe('workflow', () => {
  jest.retryTimes(3, {entireDescribe: true});

  test('first step', () => {});
  test('second step', () => {}); // a failure retries the entire block
});

New file watcher

The non-watchman path of jest-haste-map is rewritten. @parcel/watcher replaces the homegrown NodeWatcher and FSEventsWatcher (#16188), and fdir replaces the hand-rolled directory recursion in the crawler (#16187). A batch of fixes also makes watching and indexing survive locked files on Windows, watchman failures, and duplicate manual mocks (#16295, #16358, #16355, #16360).

If you can, please run your suite with --no-watchman (in and out of watch mode) to exercise the new crawler and watchers, and report anything odd 👍

Long-requested dependency updates

  • babel-plugin-istanbul is updated to v8 (#16049)
  • glob is updated to v13 (#16397)
  • source-map-support is replaced with an implementation in @jest/source-map (#16327). This fixes a memory leak where source-map-support's process-global caches pinned every finished test file's sandbox. Source maps also survive environment teardown, --testLocationInResults looks up the right column, and scheme-prefixed sources like webpack:/// are kept as-is.

Performance

  • Warm module resolution costs about a third of what it did, and repeated work is gone from the resolution hot path (#16373, #16371).
  • Per-require overhead in jest-runtime is cut: module ID resolution is skipped when no mock can apply, and core modules answer before the manual-mock probe (#16376).
  • jest-snapshot loads babel, semver and synckit lazily, so every test process loads ~200 fewer modules (#16387).
  • jest-haste-map caches the watchman socket path, so warm runs spawn no watchman processes (#16386), and reuses cached metadata for duplicated haste names instead of re-parsing them on every startup (#16351).

More new APIs

  • Snapshot failures expose the .snap file path as matcherResult.snapshotPath in failureDetails (#16374).
  • --collectTests expands test.each/describe.each cases and reports per-status counts plus a summary line that matches a real run (#16259).
  • AggregateError inner errors and nested cause chains render with code frames and per-level indentation, and are included in --json output, retryReasons and reporter annotations (#16316).

ESM

A long list of fixes brings jest-runtime's module system closer to Node's:

  • Automocking and manual __mocks__ files now apply to ESM on Node 24.9+. Static imports, dynamic import() and require() of an ESM file generate an automock from the real module's namespace instead of failing with "Attempting to import a mock without a factory" (#16391).
  • Many jest.unstable_mockModule gaps are closed: mocks apply when the mocked file is require()d directly, async factories run once and fail the import instead of crashing the worker 😅, and mocks made inside jest.isolateModules stay scoped to that block (#16389, #16365).
  • require(esm), CJS/ESM interop, import.meta, data: URIs and error ordering now match Node in dozens of edge cases. See the Fixes section for the full list (#16364 through #16391).
  • The module-sync export condition resolves, so packages that expose their ESM entry point for require() load the same file Node picks (#16336).

The intentional divergences from Node's module system are now documented on the ECMAScript Modules page (#16368).

Resolver

  • The default resolver honors Node's --preserve-symlinks / NODE_PRESERVE_SYMLINKS (#16260).
  • moduleNameMapper applies to both spellings of core module specifiers (fs and node:fs), and builtins that only exist prefixed (node:sqlite, node:test) resolve asynchronously (#16390, #16388).
  • A user resolver can be written as an ES module (#16332).

On top of the highlights there are ~60 fixes across jest-circus, jest-haste-map, jest-config, jest-mock and the transform cache keys. See the full changelog below 😀


Features

  • [@jest/expect-utils, jest-mock] Add mockFn.whenCalledWith(...args) for configuring return values per argument list, with first-class asymmetric-matcher support (#16053)
  • [@jest/expect-utils] Export AsymmetricMatcher and FunctionParameters types (previously private to expect) (#16053)
  • [jest-circus, jest-core, jest-jasmine2, jest-test-result, jest-types] --collectTests now expands test.each/describe.each cases and reports per-status counts (skipped/todo via the new wouldRun flag for selected tests) plus a summary line that match a real run, including under --testNamePattern and .only/fdescribe focus on both the circus and jasmine2 runners (#16259)
  • [jest-circus, jest-environment, jest-runtime, jest-types] Add describe-level retries via jest.retryTimes(..., {entireDescribe: true}) (#16322)
  • [jest-circus, jest-message-util, jest-reporters, jest-types] Add retryMessages to AssertionResult and export formatErrorStack, so the retry log renders nested cause and AggregateError sections with code frames instead of serialized [cause]:/[errors]: markers (#16316)
  • [jest-circus, jest-types] Add unhandledErrorsDetailed to Circus.RunResult, so an unhandled rejection reports its cause chain and AggregateError entries with code frames instead of a pre-serialized stack (#16316)
  • [jest-haste-map] Replace NodeWatcher and FSEventsWatcher with @parcel/watcher for the non-watchman watch path (#16188)
  • [jest-resolve] Bump unrs-resolver to 1.12.1, remove jest-pnp-resolver and unnecessary checks (#15721)
  • [jest-resolve] Honor Node's --preserve-symlinks / NODE_PRESERVE_SYMLINKS in the default resolver by passing symlinks: false to unrs-resolver (#16260)
  • [jest-runtime] Apply automocking and manual __mocks__ files to synchronously evaluable ESM graphs on Node 24.9+ - static imports, dynamic import() and require() of an ESM file now generate an automock from the real module's namespace instead of failing with "Attempting to import a mock without a factory". Graphs that need async evaluation (top-level await) or an async-only resolver or transformer still throw (#16391)
  • [jest-runtime] Route process.getBuiltinModule through the sandbox, so it returns the sandbox process and the hooked node:module instead of the host's (#16391)
  • [jest-runtime] Throw an actionable error from module.register() and module.registerHooks() inside a test - the hooks attached to the loader running Jest itself, never saw the sandboxed requires they were meant for, and stayed registered for every later test file in the worker (#16391)
  • [jest-runtime] Surface resolution and import-attribute errors in an ESM graph before executing any of its CJS dependencies on Node 24.9+, matching Node's run-nothing-on-a-broken-graph behavior; the legacy loader on older versions keeps its linking-time execution order (#16391)
  • [jest-runtime] Throw ERR_SOURCE_PHASE_NOT_DEFINED with an actionable message for import source and import.source(), instead of failing at instantiation with V8's bare "Source phase import object is not defined" (#16391)
  • [jest-runtime] Emit the JSON-without-import-attribute deprecation warning once per test file instead of once per worker, so it is no longer silently swallowed for every file after the first (#16391)
  • [jest-runtime] Set import.meta.main to true in the test file and false in every module it loads, matching Node 24+ (#16367)
  • [jest-runtime] Resolve the module-sync export condition, so a package that exposes its ESM entry point for require() loads the same file Node would (#16336)
  • [jest-snapshot] Add external snapshot paths to custom reporter failure details (#16374)

Fixes

  • [jest-console, jest-reporters] CustomConsole now buffers console output so TestResult.console is populated for reporters when verbose is enabled, while GitHubActionsReporter avoids replaying buffered output in verbose mode (#16155)
  • [expect, jest-message-util, jest-pattern, jest-regex-util, jest-util] Revert node: protocol imports to restore webpack/browser-bundle compatibility (#16167)
  • [expect] Widen toMatchObject and objectContaining parameter type from Record<string, unknown> to object so class instances are accepted (#16196)
  • [jest-circus] Call a generator test body with the shared test context, so this matches what a regular test function receives (#16347)
  • [jest-circus] Capture the error listeners of the parent process instead of the in-sandbox process, so listeners registered before the test file survive teardown and sandbox listeners no longer leak onto the parent (#16347)
  • [jest-circus] Clear currentlyRunningTest after skipped and todo tests (#16342)
  • [jest-circus] Prevent late done() callbacks from affecting later test or hook invocations (#16343)
  • [jest-circus, jest-jasmine2] Honor --expand when formatting node:assert failures, instead of always collapsing the diff (#16347)
  • [jest-circus, jest-jasmine2, jest-message-util] Serialize the inner errors of an AggregateError into failureMessages, retryReasons and unhandledErrors, so --json output and reporter annotations include them (#16316)
  • [jest-circus, jest-snapshot] Keep snapshot state and counts correct when a test retries (#16344)
  • [@jest/create-cache-key-function] Include the caller support flags in the generated key, so a transformer that emits ESM or CJS based on them no longer shares one cache entry between the two (#16331)
  • [@jest/create-cache-key-function] Include the stringified project config in the generated key, so editing a transformer's own settings invalidates what it cached (#16331)
  • [@jest/transform] Include the caller support flags in a transform's cache key, so a file transformed both as ESM and as CJS no longer serves one shape's output for the other (#16331)
  • [jest-config] Add missing findRelatedTests, outputFile, and replname entries to ValidConfig so they no longer trigger spurious "Unknown option" warnings (#16224)
  • [jest-config] Use --config for the global config when multiple --projects are specified (#16273)
  • [jest-core] Serialize bigint values in --json and --outputFile output as their literal form (4n), instead of failing the run with TypeError: Do not know how to serialize a BigInt (#16338)
  • [jest-core] Do not report a CustomGC async resource (used by N-API addons such as napi-rs for per-isolate GC bookkeeping) as an open handle, since it is napi_unref'd by the addon and can never keep the event loop alive (#16379)
  • [jest-each] Keep a $&, $`, $' or $$ inside a %p param value out of the replacement, so the title shows the value instead of the text around it (#16338)
  • [jest-each] Interpolate a bigint into a %j title as its literal form ("4n") at any depth, instead of throwing TypeError: Do not know how to serialize a BigInt while collecting the tests (#16338)
  • [jest-environment, jest-runtime] Bind sandboxInjectedGlobals to the right values when injectGlobals is false, instead of shifting every one of them by a position (#16377)
  • [jest-environment-node, jest-util] Only warn about a conflicting globalsCleanup mode when one was explicitly configured, and follow the mode that is actually in effect (#16323)
  • [jest-environment-node, jest-util] Stop resolving lazy globals when setting up an environment, so Node 26's builtin module globals are no longer loaded (and no longer emit their deprecation warnings) for every test file (#16324)
  • [jest-haste-map] Keep watch mode alive when an outside process briefly makes a file unreadable on Windows, instead of tearing the watcher down on EPERM (#16295)
  • [jest-haste-map] Keep indexing when an outside process holds a file open on Windows, instead of failing the whole crawl on EPERM (#16358)
  • [jest-haste-map] Keep a duplicated manual mock resolving when the file it pointed at is deleted in watch mode (#16360)
  • [jest-haste-map] Shut the worker farm down when a duplicate manual mock aborts the build under throwOnModuleCollision (#16354)
  • [jest-haste-map] Attach the watchman client's error listener before the first command, so a watchman failure falls back to the node crawler instead of crashing on an unhandled error event, and always end the client (#16355)
  • [jest-haste-map] Stop delivering watch events after WatchmanWatcher is closed, and route its warnings through the configured console (#16355)
  • [jest-haste-map] Restore the nested duplicates index correctly in ModuleMap.fromJSON, so a haste collision reported inside a test worker raises DuplicateHasteCandidatesError instead of a TypeError (#16353)
  • [jest-haste-map] Match watched files on a full extension, so moduleFileExtensions: ['js'] no longer accepts foo.mjs (#16352)
  • [jest-haste-map] Delimit the fields that make up the haste map cache key, so two different option sets cannot hash to the same cache file (#16352)
  • [jest-message-util] Print the inner errors of an AggregateError thrown inside a test (#16316)
  • [jest-message-util] Indent nested cause and AggregateError sections of a test failure by one level per depth, so the nesting is legible instead of rendering flat (#16316)
  • [jest-message-util] Color stack traces line by line so blank lines stay blank (#16316)
  • [jest-message-util] Detect Jest's own frames without assuming the checkout directory's name, and cover @jest/* packages, so stack traces and code frames point at user code (#16326)
  • [jest-mock] mockResolvedValue / mockRejectedValue now see all overload return types, so a Promise-returning overload survives even when a later overload returns a non-Promise (e.g. pg.Client['end']) (#16237)
  • [@jest-environment/jsdom-abstract] Make @types/jsdom a peer dependency (#16166)
  • [jest-mock] Remove the leftover own accessor descriptor when restoring a spyOn of an inherited getter or setter, so the instance keeps reflecting the prototype (#16226)
  • [jest-resolve] Include extensionsToTreatAsEsm in the shouldLoadAsEsm cache key, so projects with different extension lists don't read each other's answers (#16369)
  • [jest-resolve] Make getModuleIDAsync build and cache data: URI module IDs the same way as getModuleID (#16370)
  • [jest-resolve] Keep the node: prefix when resolving a core module asynchronously, so a builtin that only exists prefixed (node:sea, node:sqlite, node:test, node:test/reporters) resolves instead of failing as a missing bare package (#16388)
  • [jest-resolve] Look up manual mocks for node: protocol specifiers under the unprefixed name they are stored as (#16388)
  • [jest-resolve] Apply moduleNameMapper consistently to both spellings of core module specifiers (fs vs node:fs) (#16390)
  • [jest-resolve] Keep virtual and ordinary mock module IDs isolated across test files (#16296)
  • [jest-resolve] Guard missing require.resolve.paths (#16052)
  • [jest-resolve, jest-config, jest-runner] Support a user resolver written as an ES module (#16332)
  • [jest-resolve, jest-runtime] Throw the CJS parse error for ESM syntax in a "type": "commonjs" package or a .cjs file instead of loading it as ESM, matching Node (#16368)
  • [@jest/source-map] Keep source map sources that name a scheme, such as webpack:///, instead of resolving them into a path that does not exist (#16327)
  • [@jest/source-map] Look up --testLocationInResults positions at the right column, and keep a mapping to the first column instead of discarding it (#16327)
  • [@jest/source-map] Warn when a source map cannot be parsed, instead of silently leaving its frames untranslated (#16327)
  • [jest-runner, @jest/source-map] Keep a source-mapped stack for an error thrown after the test environment was torn down (#16327)
  • [jest-runtime, @jest/source-map] Keep source maps past teardown and past the next test file's install, so a stack from a file no earlier stack mentioned still points at the original source (#16330)
  • [jest-runtime] Report that no coverage was collected when getAllV8CoverageInfoCopy is called after teardown, instead of returning an empty result (#16385)
  • [jest-runtime] Cache a CJS module's parsed exports before walking its re-exports, so two modules that re-export each other no longer overflow the stack when imported from ESM (#16363)
  • [jest-runtime] Keep a re-exported ES module's parse failure from marking the re-exporting CommonJS file as ESM, so module.exports = require('./dep.mjs') loads instead of failing with module is not defined (#16363)
  • [jest-runtime] Scope module mocks instantiated inside jest.isolateModules/isolateModulesAsync to that block, so a mock first imported there no longer outlives it - matching how CommonJS mocks already behave (#16365)
  • [jest-runtime] Suspend module isolation while generating an automock, so loading the real module to read its shape no longer populates the isolated registry (#16365)
  • [jest-runtime] Check a cached ES module's status before require() returns it, so a module whose evaluation threw rethrows that error and one left linked by a failed sibling is evaluated instead of returning uninitialized bindings (#16364)
  • [jest-runtime] Report the original ERR_REQUIRE_ASYNC_MODULE when a require() of a top-level-await graph is retried, instead of a spurious "concurrent import()" error (#16364)
  • [jest-runtime] Throw the evaluation error when another caller's import() of the same module failed while we awaited it, instead of resolving with the errored module (#16364)
  • [jest-runtime] Mark the result of require()ing an ES module that has a default export with __esModule: true through a live-binding facade, and serve the same object from require.cache, matching Node (#16367)
  • [jest-runtime] Provide a CommonJS module's exports under the 'module.exports' named export when imported from ESM, matching Node 23+ (#16367)
  • [jest-runtime] Give the test file itself a non-null require.main (#16367)
  • [jest-runtime] Populate module.children with the modules a file loads, matching Node (#16368)
  • [jest-runtime] Provide import.meta.resolve and import.meta.jest in data: URI modules, accept any-case mediatype parameters, and use Node's error codes for invalid data: URIs (#16368)
  • [jest-runtime] Key ES modules by full URL, so query and fragment suffixes create the same module instances as Node and show up in import.meta.url (#16375)
  • [jest-runtime] Share modules between overlapping graphs when a CommonJS module require()s an ES module mid-load, instead of evaluating shared dependencies twice (#16375)
  • [jest-runtime] Throw ERR_REQUIRE_CYCLE_MODULE like Node when a CommonJS module require()s an ES module that is still being loaded, instead of evaluating the module a second time (#16366)
  • [jest-runtime] Key builtin modules in the ESM registry by one canonical specifier (#16341)
  • [jest-runtime] import.meta.resolve() for a builtin uses its node: specifier (#16341)
  • [jest-runtime] Fall back to native ESM when a .js file contains ESM syntax but has no "type":"module" marker (#16152)
  • [jest-runtime] Allow require() of ESM-marked files on Node < 24.9 via transform fallback (#16244)
  • [jest-runtime, @jest/transform] Surface actionable ERR_REQUIRE_ESM error for files with untransformed ESM syntax instead of the generic "unexpected token" message (#16244)
  • [jest-runtime] Support older test environments whose moduleMocker does not implement clearMocksOnScope (#16169)
  • [jest-runtime] Apply jest.unstable_mockModule when the mocked file itself is require()d, not only when it is imported as a dependency (#16389)
  • [jest-runtime] Apply jest.unstable_mockModule to statically imported data: URIs on Node 24.9+, matching dynamic import() (#16389)
  • [jest-runtime] Run an async jest.unstable_mockModule factory once per module instead of twice, and fail the import instead of crashing the worker when the factory rejects (#16389)
  • [jest-runtime] Hide a require(esm) module that failed to evaluate from require.cache, as Node does, instead of exposing a namespace with uninitialized bindings (#16389)
  • [jest-runtime] Strip the byte-order mark when importing a JSON module, matching require() and Node (#16389)
  • [jest-runtime] Throw ERR_REQUIRE_ASYNC_MODULE when require(esm) runs under an async-only custom resolver, instead of silently resolving with the default resolver (#16389)
  • [jest-runtime] Parse imported JSON modules with the test realm's JSON, so their objects pass instanceof Object inside the test like require()d JSON does (#16389)
  • [jest-runtime] Accept every file: URL string in the sandboxed module.createRequire, including one with a localhost authority, as Node does (#16389)
  • [jest-runtime] Point at {virtual: true} when jest.mock or jest.unstable_mockModule is given a module that cannot be resolved (#16389)
  • [jest-reporters] Fix coverage report table formatting in CI/GitHub Actions environments where process.stdout.columns is undefined by falling back to the COLUMNS env var or 80 columns in CI, preserving existing behaviour in other non-TTY environments (#16227)
  • [jest-runtime] Support CJS-in-ESM exports via "module.exports" named exports (#16277)
  • [jest-snapshot] Keep a skipped or failed test's hinted snapshots, instead of reporting them obsolete (#16348)
  • [jest-util] Stop globsToMatcher reusing a cached matcher compiled with different picomatch options, and keep its dot: true default when dot is passed as undefined (#16381)
  • [pretty-format] Move the react-is aliases into the @jest scope, so they cannot be shadowed by unrelated packages published under the alias names (#16333)

Chore & Maintenance

  • [docs] Document the intentional divergences from Node's module system in the ECMAScript Modules page (#16368)
  • [docs] Note deprecation of react-test-renderer in React Native tutorial and pretty-format README (#16294)
  • [docs] Use @testing-library/react-native in the React Native tutorial instead of the deprecated react-test-renderer (#16318)
  • [babel-jest, @jest/transform] Update babel-plugin-istanbul to v8 (#16049)
  • [jest-config, @jest/reporters, jest-runtime] Update glob to v13 (#16397)
  • [jest-haste-map] Refactor massive class into multiple files (#16180)
  • [jest-haste-map] Drop walker dependency; replace hand-rolled directory recursion in the JS crawler and watcher startup with fdir (#16187)
  • [jest-haste-map] Reuse cached metadata for files whose haste name is a known duplicate, instead of re-reading and re-parsing them on every startup (#16351)
  • [jest-haste-map] Cache the watchman socket path and replace the watchman --version probe with get-sockname, so warm runs spawn no watchman processes (#16386)
  • [jest-resolve] Store the per-directory package-type lookup in the cache it reads, so it actually memoizes (#16369)
  • [jest-resolve, jest-runtime] Cut repeated work on the resolution hot path: hoist the platform-extension list to construction, memoize isCoreModule and the options cache-key serialization, skip mapper preparation when no moduleNameMapper is configured, run each mapper regex once, and stop re-parsing NODE_OPTIONS on every default-resolver call (#16371)
  • [jest-resolve] Cut warm resolution cost to about a third: reuse one unrs-resolver factory per options shape instead of cloning per resolution, compose the factory cache key from per-array cached strings instead of serializing options, and stop constructing an Error for misses that findNodeModule swallows; add a __benchmarks__ suite for the default resolver (#16373)
  • [jest-runner, @jest/source-map] Replace source-map-support with an implementation in @jest/source-map (#16327)
  • [jest-snapshot] Load babel, semver and synckit lazily, so requiring the package (which every test process does through @jest/expect) no longer loads ~200 modules that only writing inline snapshots needs (#16387)
  • [jest-runtime] Reduce per-require overhead: skip module ID resolution when no mock can apply, answer core modules before probing for a manual mock, share one require.cache proxy across modules, and cache empty files (#16376)
  • [@jest/source-map] Deprecate getCallsite in favour of SourceMapSupport#getCallsite (#16327)
  • [jest-runtime] Avoid magical null value in ESM loader (#16160)

New Contributors

Full Changelog: v30.4.2...v30.5.0

30.0.1

What's Changed

Features

  • [jest-resolver] Implement the defaultAsyncResolver (#15679)

Fixes

  • [jest-resolver] Resolve builtin modules correctly (#15683)
  • [jest-environment-node, jest-util] Avoid setting globals cleanup protection symbol when feature is off (#15684)

Chore & Maintenance

  • [*] Remove and deprecate jest-repl package (#15673)
  • [jest-resolver] Replace custom isBuiltinModule with node's isBuiltin (#15685)

New Contributors

Full Changelog: https://github.com/jestjs/jest/blob/main/CHANGELOG.md

30.0.0

Today we are happy to announce the release of Jest 30. This release features a substantial number of changes, fixes, and improvements. While it is one of the largest major releases of Jest ever, we admit that three years for a major release is too long. In the future, we are aiming to make more frequent major releases to keep Jest great for the next decade.

If you want to skip all the news and just get going, run npm install jest@^30.0.0 and follow the migration guide: Upgrading from Jest 29 to 30.

Read the full blog post

Features

  • [*] Renamed globalsCleanupMode to globalsCleanup and --waitNextEventLoopTurnForUnhandledRejectionEvents to --waitForUnhandledRejections
  • [expect] Add ArrayOf asymmetric matcher for validating array elements. (#15567)
  • [babel-jest] Add option excludeJestPreset to allow opting out of babel-preset-jest (#15164)
  • [expect] Revert #15038 to fix expect(fn).toHaveBeenCalledWith(expect.objectContaining(...)) when there are multiple calls (#15508)
  • [jest-circus, jest-cli, jest-config] Add waitNextEventLoopTurnForUnhandledRejectionEvents flag to minimise performance impact of correct detection of unhandled promise rejections introduced in #14315 (#14681)
  • [jest-circus] Add a waitBeforeRetry option to jest.retryTimes (#14738)
  • [jest-circus] Add a retryImmediately option to jest.retryTimes (#14696)
  • [jest-circus, jest-jasmine2] Allow setupFilesAfterEnv to export an async function (#10962)
  • [jest-circus, jest-test-result] Add startedAt timestamp in TestCaseResultObject within onTestCaseResult (#15145)
  • [jest-cli] Export buildArgv (#15310)
  • [jest-config] [BREAKING] Add mts and cts to default moduleFileExtensions config (#14369)
  • [jest-config] [BREAKING] Update testMatch and testRegex default option for supporting mjs, cjs, mts, and cts (#14584)
  • [jest-config] Loads config file from provided path in package.json (#14044)
  • [jest-config] Allow loading jest.config.cts files (#14070)
  • [jest-config] Show rootDir in error message when a preset fails to load (#15194)
  • [jest-config] Support loading TS config files using esbuild-register via docblock loader (#15190)
  • [jest-config] Allow passing TS config loader options via docblock comment (#15234)
  • [jest-config] If Node is running with type stripping enabled, do not require a TS loader (#15480)
  • [@jest/core] Group together open handles with the same stack trace (#13417, & #14789)
  • [@jest/core] Add perfStats to surface test setup overhead (#14622)
  • [@jest/core] [BREAKING] Changed --filter to accept an object with shape { filtered: Array<string> } to match documentation (#13319)
  • [@jest/core] Support --outputFile option for --listTests (#14980)
  • [@jest/core] Stringify Errors properly with --json flag (#15329)
  • [@jest/core, @jest/test-sequencer] [BREAKING] Exposes globalConfig & contexts to TestSequencer (#14535, & #14543)
  • [jest-each] Introduce %$ option to add number of the test to its title (#14710)
  • [@jest/environment] [BREAKING] Remove deprecated jest.genMockFromModule() (#15042)
  • [@jest/environment] [BREAKING] Remove unnecessary defensive code (#15045)
  • [jest-environment-jsdom] [BREAKING] Upgrade JSDOM to v22 (#13825)
  • [@jest/environment-jsdom-abstract] Introduce new package which abstracts over the jsdom environment, allowing usage of custom versions of JSDOM (#14717)
  • [jest-environment-node] Update jest environment with dispose symbols Symbol (#14888 & #14909)
  • [expect, @jest/expect] [BREAKING] Add type inference for function parameters in CalledWith assertions (#15129)
  • [@jest/expect-utils] Properly compare all types of TypedArrays (#15178)
  • [@jest/fake-timers] [BREAKING] Upgrade @sinonjs/fake-timers to v13 (#14544 & #15470)
  • [@jest/fake-timers] Exposing new modern timers function advanceTimersToFrame() which advances all timers by the needed milliseconds to execute callbacks currently scheduled with requestAnimationFrame (#14598)
  • [jest-matcher-utils] Add SERIALIZABLE_PROPERTIES to allow custom serialization of objects (#14893)
  • [jest-mock] Add support for the Explicit Resource Management proposal to use the using keyword with jest.spyOn(object, methodName) (#14895)
  • [jest-reporters] Add support for DEC mode 2026 (#15008)
  • [jest-resolver] Support file:// URLs as paths (#15154)
  • [jest-resolve,jest-runtime,jest-resolve-dependencies] Pass the conditions when resolving stub modules (#15489)
  • [jest-runtime] Exposing new modern timers function jest.advanceTimersToFrame() from @jest/fake-timers (#14598)
  • [jest-runtime] Support import.meta.filename and import.meta.dirname (available from Node 20.11) (#14854)
  • [jest-runtime] Support import.meta.resolve (#14930)
  • [jest-runtime] [BREAKING] Make it mandatory to pass globalConfig to the Runtime constructor (#15044)
  • [jest-runtime] Add unstable_unmockModule (#15080)
  • [jest-runtime] Add onGenerateMock transformer callback for auto generated callbacks (#15433 & #15482)
  • [jest-runtime] [BREAKING] Use vm.compileFunction over vm.Script (#15461)
  • [@jest/schemas] Upgrade @sinclair/typebox to v0.34 (#15450)
  • [@jest/types] test.each(): Accept a readonly (as const) table properly (#14565)
  • [@jest/types] Improve argument type inference passed to test and describe callback functions from each tables (#14920)
  • [jest-snapshot] [BREAKING] Add support for Error causes in snapshots (#13965)
  • [jest-snapshot] Support Prettier 3 (#14566)
  • [@jest/util-snapshot] Extract utils used by tooling from jest-snapshot into its own package (#15095)
  • [pretty-format] [BREAKING] Do not render empty string children ('') in React plugin (#14470)

Fixes

  • [expect] Show AggregateError to display (#15346)
  • [*] Replace exit with exit-x (#15399)
  • [babel-plugin-jest-hoist] Use denylist instead of the deprecated blacklist for Babel 8 support (#14109)
  • [babel-plugin-jest-hoist] Do not rely on buggy Babel behaviour (#15415)
  • [expect] Check error instance type for toThrow/toThrowError (#14576)
  • [expect] Improve diff for failing expect.objectContaining (#15038)
  • [expect] Use Array.isArray to check if an array is an Array (#15101)
  • [expect] Fix Error cause assertion errors (#15339)
  • [jest-changed-files] Print underlying errors when VCS commands fail (#15052)
  • [jest-changed-files] Abort sl root call if output resembles a steam locomotive (#15053)
  • [jest-circus] [BREAKING] Prevent false test failures caused by promise rejections handled asynchronously (#14315)
  • [jest-circus] Replace recursive makeTestResults implementation with iterative one (#14760)
  • [jest-circus] Omit expect.hasAssertions() errors if a test already has errors (#14866)
  • [jest-circus, jest-expect, jest-snapshot] Pass test.failing tests when containing failing snapshot matchers (#14313)
  • [jest-circus] Concurrent tests now emit jest circus events at the correct point and in the expected order. (#15381)
  • [jest-cli] [BREAKING] Validate CLI flags that require arguments receives them (#14783)
  • [jest-config] Make sure to respect runInBand option (#14578)
  • [jest-config] Support testTimeout in project config (#14697)
  • [jest-config] Support coverageReporters in project config (#14697)
  • [jest-config] Allow reporters in project config (#14768)
  • [jest-config] Allow Node16/NodeNext/Bundler moduleResolution in project's tsconfig (#14739)
  • [@jest/create-cache-key-function] Correct the return type of createCacheKey (#15159)
  • [jest-each] Allow $keypath templates with null or undefined values (#14831)
  • [@jest/expect-utils] Fix comparison of DataView (#14408)
  • [@jest/expect-utils] [BREAKING] exclude non-enumerable in object matching (#14670)
  • [@jest/expect-utils] Fix comparison of URL (#14672)
  • [@jest/expect-utils] Check Symbol properties in equality (#14688)
  • [@jest/expect-utils] Catch circular references within arrays when matching objects (#14894)
  • [@jest/expect-utils] Fix not addressing to Sets and Maps as objects without keys (#14873)
  • [jest-haste-map] Fix errors or clobbering with multiple hasteImplModulePaths (#15522)
  • [jest-leak-detector] Make leak-detector more aggressive when running GC (#14526)
  • [jest-runtime] Properly handle re-exported native modules in ESM via CJS (#14589)
  • [jest-runtime] Refactor _importCoreModel so required core module is consistent if modified while loading (#15077)
  • [jest-schemas, jest-types] [BREAKING] Fix type of testFailureExitCode config option(#15232)
  • [jest-util] Make sure isInteractive works in a browser (#14552)
  • [pretty-format] [BREAKING] Print ArrayBuffer and DataView correctly (#14290)
  • [pretty-format] Fixed a bug where "anonymous custom elements" were not being printed as expected. (#15138)
  • [jest-cli] When specifying paths on the command line, only match against the relative paths of the test files (#12519)
    • [BREAKING] Changes testPathPattern configuration option to testPathPatterns, which now takes a list of patterns instead of the regex.
    • [BREAKING] --testPathPattern is now --testPathPatterns
    • [BREAKING] Specifying testPathPatterns when programmatically calling watch must be specified as new TestPathPatterns(patterns), where TestPathPatterns can be imported from @jest/pattern
  • [jest-reporters, jest-runner] Unhandled errors without stack get correctly logged to console (#14619)
  • [jest-util] Always load mjs files with import (#15447)
  • [jest-worker] Properly handle a circular reference error when worker tries to send an assertion fails where either the expected or actual value is circular (#15191)
  • [jest-worker] Properly handle a BigInt when worker tries to send an assertion fails where either the expected or actual value is BigInt (#15191)
  • [expect] Resolve issue where ObjectContaining matched non-object values. ([#15463])(#15463).
    • Adds a conditional/check to ensure the argument passed to expect is an object.
    • Add unit tests for new ObjectContaining behavior.
    • Remove invalid/wrong test case assertions for ObjectContaining.
  • [jest-worker] Addresses incorrect state on exit (#15610)

Performance

  • [*] [BREAKING] Bundle all of Jest's modules into index.js (#12348, #14550 & #14661)
  • [jest-haste-map] Only spawn one process to check for watchman installation (#14826)
  • [jest-runner] Better cleanup source-map-support after test to resolve (minor) memory leak (#15233)
  • [jest-circus, jest-environment-node, jest-repl, jest-runner, jest-util] Cleanup global variables on environment teardown to reduce memory leaks (#15215 & #15636 & #15643)

Chore & Maintenance

  • [jest-environment-jsdom, jest-environment-jsdom-abstract] Increased version of jsdom to ^26.0.0 (#15325CVE-2024-37890)
  • [*] Increase version of micromatch to ^4.0.7 (#15082)
  • [*] [BREAKING] Drop support for Node.js versions 14, 16, 19, 21 and 23 (#14460, #15118, #15623, #15640)
  • [*] [BREAKING] Drop support for typescript@4.3, minimum version is now 5.4 (#14542, #15621)
  • [*] Depend on exact versions of monorepo dependencies instead of ^ range (#14553)
  • [*] [BREAKING] Add ESM wrapper for all of Jest's modules (#14661)
  • [*] [BREAKING] Upgrade to glob@10 (#14509)
  • [*] Use TypeError over Error where appropriate (#14799)
  • [docs] Fix typos in CHANGELOG.md and packages/jest-validate/README.md (#14640)
  • [docs] Don't use alias matchers in docs (#14631)
  • [babel-jest, babel-preset-jest] [BREAKING] Increase peer dependency of @babel/core to ^7.11 (#14109)
  • [babel-jest, @jest/transform] Update babel-plugin-istanbul to v6 (#15156)
  • [babel-plugin-jest-hoist] Move unnecessary dependencies to devDependencies (#15010)
  • [expect] [BREAKING] Remove .toBeCalled(), .toBeCalledTimes(), .toBeCalledWith(), .lastCalledWith(), .nthCalledWith(), .toReturn(), .toReturnTimes(), .toReturnWith(), .lastReturnedWith(), .nthReturnedWith() and .toThrowError() matcher aliases (#14632)
  • [jest-cli, jest-config, @jest/types] [BREAKING] Remove deprecated --init argument (#14490)
  • [jest-config, @jest/core, jest-util] Upgrade ci-info (#14655)
  • [jest-mock] [BREAKING] Remove MockFunctionMetadataType, MockFunctionMetadata and SpyInstance types (#14621)
  • [@jest/reporters] Upgrade istanbul-lib-source-maps (#14924)
  • [jest-schemas] Upgrade @sinclair/typebox (#14775)
  • [jest-transform] Upgrade write-file-atomic (#14274)
  • [jest-util] Upgrade picomatch to v4 (#14653 & #14885)
  • [docs] Append to NODE_OPTIONS, not overwrite ([#14730](https://github.com/jestjs/jest/pull/14730))
  • [docs] Updated .toHaveBeenCalled() documentation to correctly reflect its functionality (#14842)
  • [docs] Link NestJS documentation on testing with Jest (#14940)
  • [docs] Revised documentation for .toHaveBeenCalled() to accurately depict its functionality. (#14853)
  • [docs] Removed ExpressJS reference link from documentation due to dead link (#15270)
  • [docs] Correct broken links in docs (#15359)

See the CHANGELOG.

29.6.3

Fixes

  • [expect, @jest/expect-utils] ObjectContaining support symbol as key (#14414)
  • [expect] Remove @types/node from dependencies (#14385)
  • [jest-core] Use workers in watch mode by default to avoid crashes (#14059 & #14085).
  • [jest-reporters] Update istanbul-lib-instrument dependency to v6. (#14401)
  • [jest-mock] Revert #13692 as it was a breaking change (#14429)
  • [jest-mock] Revert #13866 as it was a breaking change (#14429)
  • [jest-mock] Revert #13867 as it was a breaking change (#14429)
  • [@jest/reporters] Marks Reporter's hooks as optional (#14433)
  • [jest-runtime] Fix dynamic ESM import module bug when loaded module through jest.isolateModulesAsync (#14397)

Chore & Maintenance

  • [jest-changed-files, jest-circus, jest-console, @jest/core, @jest/runtime, @jest/transform] Use invariant and notEmpty from jest-util rather than own internal (#14366)

New Contributors

Full Changelog: v29.6.2...v29.6.3

29.6.0

Features

  • [jest-circus, jest-snapshot] Add support for snapshot matchers in concurrent tests (#14139)
  • [jest-cli] Include type definitions to generated config files (#14078)
  • [jest-snapshot] Support arrays as property matchers (#14025)
  • [jest-core, jest-circus, jest-reporter, jest-runner] Added support for reporting about start individual test cases using jest-circus (#14174)

Fixes

  • [jest-circus] Prevent false test failures caused by promise rejections handled asynchronously (#14110)
  • [jest-config] Handle frozen config object (#14054)
  • [jest-config] Allow coverageDirectory and collectCoverageFrom in project config (#14180)
  • [jest-core] Always use workers in watch mode to avoid crashes (#14059).
  • [jest-environment-jsdom, jest-environment-node] Fix assignment of customExportConditions via testEnvironmentOptions when custom env subclass defines a default value (#13989)
  • [jest-matcher-utils] Fix copying value of inherited getters (#14007)
  • [jest-mock] Tweak typings to allow jest.replaceProperty() replace methods (#14008)
  • [jest-mock] Improve user input validation and error messages of spyOn and replaceProperty methods (#14087)
  • [jest-runtime] Bind jest.isolateModulesAsync to this (#14083)
  • [jest-runtime] Forward wrapperLength to the Script constructor as columnOffset for accurate debugging (#14148)
  • [jest-runtime] Guard _isMockFunction access with in (#14188)
  • [jest-snapshot] Fix a potential bug when not using prettier and improve performance (#14036)
  • [@jest/transform] Do not instrument .json modules (#14048)

Chore & Maintenance

  • [*] Update semver dependency to get vulnerability fix (#14262)
  • [docs] Updated documentation for the --runTestsByPath CLI command (#14004)
  • [docs] Updated documentation regarding the synchronous fallback when asynchronous code transforms are unavailable (#14056)
  • [docs] Update jest statistics of use and downloads in website Index.

New Contributors

Full Changelog: v29.5.0...v29.6.0

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ @​jest/test-sequencer (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ @​jest/transform (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ @​jest/types (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ @​jridgewell/gen-mapping (indirect, 0.1.1 → 0.3.13) · Repo · Changelog

Release Notes

0.3.5

What's Changed

Full Changelog: v0.3.4...v0.3.5

0.3.4

Full Changelog: v0.3.3...v0.3.4

0.3.3

Full Changelog: v0.3.2...v0.3.3

0.3.2

Internal

New Contributors

  • @ljharb made their first contribution in #4

Full Changelog: v0.3.1...v0.3.2

Does any of this look wrong? Please let us know.

↗️ @​jridgewell/sourcemap-codec (indirect, 1.4.14 → 1.6.0) · Repo · Changelog

Release Notes

1.6.0 (from changelog)

  • Add Range Mapping support: #45
    • includes new decodeRangeMappings and encodeRangeMappings APIs

Full Changelog: sourcemap-codec/1.5.5...sourcemap-codec/1.6.0

Does any of this look wrong? Please let us know.

↗️ @​jridgewell/trace-mapping (indirect, 0.3.18 → 0.3.31) · Repo · Changelog

Release Notes

0.3.24

What's Changed

  • Add ignoreList (and x_google_ignoreList) support: 1027ce6

Full Changelog: v0.3.23...v0.3.24

0.3.23

Full Changelog: v0.3.22...v0.3.23

0.3.22

What's Changed

Full Changelog: v0.3.21...v0.3.22

0.3.21

What's Changed

Full Changelog: v0.3.20...v0.3.21

0.3.20

What's Changed

  • Fix handling of sectioned source maps missing 'names' array by @RandomByte in #29

New Contributors

Full Changelog: v0.3.19...v0.3.20

0.3.19

What's Changed

  • Unpins the @jridgewell/resolve-uri and @jridgewell/sourcemap-codec dependencies so they can be de-duped.

Full Changelog: v0.3.16...v0.3.17

Does any of this look wrong? Please let us know.

↗️ @​sinclair/typebox (indirect, 0.24.19 → 0.34.52) · Repo · Changelog

Release Notes

0.25.24 (from changelog)

Updates:

  • 331 Implements an additional check specific to property types of required & undefined. This to ensure the property key exists when the property value extends undefined.
  • 331 Documentation updates for Ajv and TypeCompiler

Additional:

  • 331 Remove unusued recursive code paths for create and cast.

0.25.23 (from changelog)

Updates:

  • 324 TypeScript Language Service now presents JSDoc comments when inferring static object properties. (IntelliSense)
  • 325 Additional property inference optimizations.

Additional:

  • Huge thank you to Github user stevezhu for these excellent contributions.

0.25.22 (from changelog)

Updates:

  • 323 adds compiler support for UTF-16 (unicode) characters for schema identifiers.

0.25.18 (from changelog)

Updates:

  • 307 implements date conversion when casting values with Value.Cast(Type.Date(), ...). Castable values include numbers (interpretted as timestamps) and iso8601 string values. Uncastable values will result in dates with values of 1970-01-01T00:00:00.000Z. This version also includes more robust checks for Dates initialized with invalid values.

0.25.11 (from changelog)

Updates:

  • 286 implements a FNV1A-64 non cryptographic hashing function in TypeBox. This function should not be used in place of cryptographic hashing functions, rather it's purpose is to provide relatively fast, hashing mechanism to assist with checks for arrays with uniqueItems constraints, specifically for cases where the array may contains reference values (such as objects, arrays, Dates and Uint8Array). This function is provided via Value.Hash() for convenience as the hash may be useful to generate a numeric identifier for values (with some considerations to React array rendering in absence of key or identifier)

0.25.10 (from changelog)

Updates:

  • 283 Updates the custom type validator callback signature to accept a schema instance. The schema instance may include additional constraints (such as options) that may be used during the validation process. Custom.Set('<Kind>', (schema, value) => { ... }).

0.25.9 (from changelog)

Updates:

  • 282 TypeBox now supports custom types. These types require the user to specify a custom [Kind] string on the type. Custom types can be registered via Custom.Set('<Kind>', (value) => { ... }) which allow the TypeCompiler and Value API's to make use of user defined validation logic.

0.25.0 (from changelog)

Updates:

  • 271 Adds a new non-standard Type.Date() type. This type joins the existing Type.UInt8Array() as a promoted extended type used to represent core JavaScript primitives. It's inclusion was prompted by end user requirements to validate Date objects prior to writing them to Date supported API's and where serialization of the Date object is handled internally by the API.

  • 271 Redesign of Extended Type representations. Extended types been updated to provide external validators (such as Ajv) additional standard proporties to use when defining the custom schema. These properties are instanceOf (used for validating a class object instances), and typeOf (when validating value types). Information on configuring Ajv for these properties can be found in the Ajv section of the TypeBox readme.

0.24.49 (from changelog)

Updates:

  • 264 TypeBox now provides preliminary support for non-boolean additionalProperties. This allows existing TObject schemas to be augmented with additional properties of a known type.

Additional:

  • TypeBox provides an additional reference codegen module for generating raw JSON Schema from TypeScript types via the TS compiler API. This generator may be used in future tooling.

0.24.44 (from changelog)

Updates:

  • 189 Both Value.Error(T, value) and TypeCheck.Error(value) now return an iterator for validation errors.
  • 191 TypeBox now provides a TypeGuard API that can be used to check the structural validity of TypeBox type. The TypeGuard can be used in reflection / code generation scenarios to resolve the appropriate inner TSchema type while traversing a outer type.
  • 197 TypeBox now implements conditional runtime type mapping. This functionality is offered as seperate import for the 0.24.0 release but may be provided as standard type in later releases. This API enables type T = Foo extends Bar ? true : false conditional checks to be implemented at runtime. This API also provides the Exclude and Extract utility types which are implemented through conditional types in TypeScript.
  • 199 TypeBox now provides better support for varidiac function and constructor signatures. Currently Variadics are mapped through Tuple types.
  • 200 The types TPick and TOmit now support types of TUnion<TLiteral<string>[]> to be used to select properties. Additionally, KeyOf now returns TUnion<TLiteral<string>[]>, allowing KeyOf schemas to be passed to TPick and TOmit.
  • 214 TypeBox now provides better support for i18n. To achieve this, TypeBox includes fixed mappable error codes on the ValueError type. These codes can be used by external implementors to create localized error messages. TypeBox may include localized error codes as an optional import in future releases.
  • 288 TypeBox now allows users to implement custom string validator formats. These formats are internally shared between the Value and TypeCompiler API's. TypeBox does not currently provide any built in formats, however the standard expected set (email, uuid, uri, etc) may be provided via optional import (inline with ajv-formats usage)
  • 229 The Value.Cast() function now implements automatic coersion of string, number and boolean types.
  • 231 TypeBox provides a new Value.Diff<T>() and Value.Patch<T>() utility API for JavaScript values. This API is intended to provide a basis for the efficient transmission of state updates across a network. This API can diff any JavaScript value (typed or untyped) but is recommended to be used in conjunction with a formal static type.
  • 236 TypeBox now implements the TNever type. This type is analogous to TypeScript's never type and is used in instances a composition results in a non-reconcilable type. Currently this type is implemented for empty TUnion<[]> types only. Future releases may utilize this type for planned updates to TIntersect (for example string & number resolves to never)
  • 241 247 TypeBox now exposes a ValuePointer API that can be used to mutate a value via an RFC6901 JSON Pointer. Previously this functionality was internally used by Value.Diff() and Value.Patch() functions but is now offered as an optional import for implementations that need to update values manually through pointer references.

Additional:

  • This project now includes two reference code generation utilities that can be used in custom build tooling. The first is TypeScriptCodeGen which will remap TypeScript interface and type definitions to TypeBox types. The second is TypeBoxCodeGen which will map existing TypeBox types into TypeScript type definitions. These implementations are not expected to be part of the TypeBox package, but users are free to clone and enhance them in their existing tool chains. Reference implementations can be found https://github.com/sinclairzx81/typebox/tree/master/codegen

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 2 commits:

↗️ @​sinonjs/fake-timers (indirect, 9.1.2 → 15.4.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ @​types/babel__core (indirect, 7.1.19 → 7.20.5) · Repo

Sorry, we couldn’t find anything useful about this release.

↗️ @​types/babel__generator (indirect, 7.6.4 → 7.27.0) · Repo

Sorry, we couldn’t find anything useful about this release.

↗️ @​types/babel__template (indirect, 7.4.1 → 7.4.4) · Repo

Sorry, we couldn’t find anything useful about this release.

↗️ @​types/babel__traverse (indirect, 7.17.1 → 7.28.0) · Repo

Sorry, we couldn’t find anything useful about this release.

↗️ @​types/istanbul-lib-coverage (indirect, 2.0.4 → 2.0.6) · Repo

Sorry, we couldn’t find anything useful about this release.

↗️ @​types/istanbul-lib-report (indirect, 3.0.0 → 3.0.3) · Repo

Sorry, we couldn’t find anything useful about this release.

↗️ @​types/istanbul-reports (indirect, 3.0.1 → 3.0.4) · Repo

Sorry, we couldn’t find anything useful about this release.

↗️ @​types/stack-utils (indirect, 2.0.1 → 2.0.3) · Repo

Sorry, we couldn’t find anything useful about this release.

↗️ @​types/yargs (indirect, 17.0.10 → 17.0.35) · Repo

Sorry, we couldn’t find anything useful about this release.

↗️ @​types/yargs-parser (indirect, 21.0.0 → 21.0.3) · Repo

Sorry, we couldn’t find anything useful about this release.

↗️ anymatch (indirect, 3.1.2 → 3.1.3) · Repo

Release Notes

3.1.3

Fixes:

  • Keep trailing slash on paths
  • Add TypeScript overload for test string being null

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 5 commits:

↗️ babel-jest (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ babel-plugin-istanbul (indirect, 6.1.1 → 8.0.0) · Repo · Changelog

Release Notes

8.0.0

8.0.0 (2025-09-25)

⚠ BREAKING CHANGES

  • deps: update to latest version of test-exclude (#301)

Features

  • deps: update to latest version of test-exclude (#301) (fb1d78c)

7.0.1

Bug Fixes

7.0.0

⚠ BREAKING CHANGES

  • Drop support for Node versions 8 and 10

Bug Fixes

  • container is falsy error with block scoping transform (#291) (8e76919)
  • update istanbul-lib-instrument to v6 (#292) (643e080)

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 11 commits:

↗️ babel-plugin-jest-hoist (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ babel-preset-current-node-syntax (indirect, 1.0.1 → 1.2.0) · Repo

Release Notes

1.1.0

New features

  • Add support for import attributes (#11)

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 16 commits:

↗️ babel-preset-jest (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ browserslist (indirect, 4.20.2 → 4.28.8) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ caniuse-lite (indirect, 1.0.30001320 → 1.0.30001810) · Repo · Changelog

↗️ ci-info (indirect, 3.3.2 → 4.4.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ cjs-module-lexer (indirect, 1.2.2 → 2.2.1) · Repo · Changelog

Release Notes

2.2.1

What's Changed

New Contributors

Full Changelog: 2.2.0...2.2.1

2.2.0

What's Changed

  • remove use of eval by doing our own string parsing by @bakkot in #118

New Contributors

Full Changelog: 2.1.1...2.2.0

2.1.1

What's Changed

New Contributors

Full Changelog: 2.1.0...2.1.1

2.1.0

What's Changed

  • Add instructions for creating a release to the readme. by @mhdawson in #109
  • fix: restore configuration through env variables by @mhdawson in #111

Full Changelog: 2.0.0...2.1.0

2.0.0

What's Changed

New Contributors

Full Changelog: 1.4.1...2.0.0

1.4.2

What's Changed

New Contributors

Full Changelog: 1.4.1...1.4.2

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 38 commits:

↗️ cliui (indirect, 7.0.4 → 8.0.1) · Repo · Changelog

Release Notes

8.0.1

8.0.1 (2022-10-01)

Bug Fixes

  • deps: move rollup-plugin-ts to dev deps (#124) (7c8bd6b)

8.0.0

8.0.0 (2022-09-30)

BREAKING CHANGES

Bug Fixes

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 6 commits:

↗️ collect-v8-coverage (indirect, 1.0.1 → 1.0.3) · Repo · Changelog

Release Notes

1.0.3

1.0.3 (2025-10-15)

Bug Fixes

  • enable and disable debugger for more accurate coverage (#235) (44fdef5)

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ cross-spawn (indirect, 7.0.3 → 7.0.6) · Repo · Changelog

Security Advisories 🚨

🚨 Regular Expression Denial of Service (ReDoS) in cross-spawn

Versions of the package cross-spawn before 7.0.5 are vulnerable to Regular Expression Denial of Service (ReDoS) due to improper input sanitization. An attacker can increase the CPU usage and crash the program by crafting a very large and well crafted string.

Release Notes

7.0.6 (from changelog)

Bug Fixes

  • update cross-spawn version to 7.0.5 in package-lock.json (f700743)

7.0.5 (from changelog)

Bug Fixes

  • fix escaping bug introduced by backtracking (640d391)

7.0.4 (from changelog)

Bug Fixes

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 15 commits:

↗️ dedent (indirect, 0.7.0 → 1.7.2) · Repo · Changelog

Release Notes

1.7.2

What's Changed

New Contributors

Full Changelog: v1.7.1...v1.7.2

1.7.0

What's Changed

New Contributors

Full Changelog: v1.6.0...v1.7.0

1.6.0

What's Changed

  • feat: add trimWhitespace option by @43081j in #97

New Contributors

Full Changelog: v1.5.3...v1.6.0

1.5.3

What's Changed

Full Changelog: v1.5.2...v1.5.3

1.5.2

What's Changed

New Contributors

Full Changelog: v1.5.1...v1.5.2

1.5.1

  • fix: add missing dedent.d.mts entry to package.json files (#73)

1.5.0

  • feat: add options with escapeSpecialCharacters (#65)

1.4.0

  • fix: fix missing ESM type definition file (#67)
  • fix: consume first level of escaping of $ and { characters (#46)

1.3.0

  • fix: add missing exports field to package.json (#59)

1.0.0

This version was given the beta tag in npm.

  • fix: add babel-plugin-add-module-exports (#40)
  • build: publish ESM and .d.ts (#32)
  • build: re-run build to refresh dist/dedent.js (#38)

Note: although this was a new major version, it contains no breaking changes from 0.x.
The versioning intent was purely to signal that the API is stable.

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 63 commits:

↗️ deepmerge (indirect, 4.2.2 → 4.3.1) · Repo · Changelog

Release Notes

4.3.1 (from changelog)

  • Fix type definition for arrayMerge options. #239

4.3.0 (from changelog)

  • Avoid thrown errors if the target doesn't have propertyIsEnumerable. #252

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 20 commits:

↗️ electron-to-chromium (indirect, 1.4.96 → 1.5.416) · Repo · Changelog

Commits

See the full diff on Github. The new version differs by 2 commits:

↗️ emittery (indirect, 0.10.2 → 0.13.1) · Repo

Release Notes

0.13.1

v0.13.0...v0.13.1

0.13.0

  • Internal: Properly clean up listener storage (#103) 3641e7a

v0.12.1...v0.13.0

0.12.1

  • Internal: Use a different approach to prevent consumers from emitting meta events (#98) c07c783

v0.12.0...v0.12.1

0.12.0

  • Add an off method to the promise returned from .once() (#100) e0b4ba7
  • Make Emittery.mixin type support arguments in constructor 32ddcbe

v0.11.0...v0.12.0

0.11.0

v0.10.2...v0.11.0

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 12 commits:

↗️ escalade (indirect, 3.1.1 → 3.2.0) · Repo

Release Notes

3.2.0

Patches

  • Declare separate ESM and CommonJS TypeScript definitions: a72e1c3
    Previously, only ESM definitions were shipped but were exported in a way that could cause tool/resolution ambiguity.

Chores

  • Update Node.js version matrix in CI suite: a8c6820

Full Changelog: v3.1.2...v3.2.0

3.1.2

Patches

Chores


Full Changelog: v3.1.1...v3.1.2

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 7 commits:

↗️ expect (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ fb-watchman (indirect, 2.0.1 → 2.0.2) · Repo

Sorry, we couldn’t find anything useful about this release.

↗️ graceful-fs (indirect, 4.2.9 → 4.2.11) · Repo

Commits

See the full diff on Github. The new version differs by 15 commits:

↗️ import-local (indirect, 3.1.0 → 3.2.0) · Repo

Release Notes

3.2.0

v3.1.0...v3.2.0

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 3 commits:

↗️ istanbul-lib-coverage (indirect, 3.2.0 → 3.2.2) · Repo · Changelog

Release Notes

3.2.2 (from changelog)

Bug Fixes

3.2.1 (from changelog)

Bug Fixes

Does any of this look wrong? Please let us know.

↗️ istanbul-lib-instrument (indirect, 5.2.0 → 6.0.3) · Repo · Changelog

Release Notes

6.0.3 (from changelog)

Bug Fixes

  • allow use of importAttributes Babel parser plugin (#786) (a44a124)

6.0.2 (from changelog)

Bug Fixes

6.0.1 (from changelog)

Bug Fixes

6.0.0 (from changelog)

⚠ BREAKING CHANGES

  • deps: minimum Node version bumped to 10.

Bug Fixes

5.2.1 (from changelog)

Bug Fixes

  • handle error when inputSourceMap is not a plain object (#662) (3e3611f)

Does any of this look wrong? Please let us know.

↗️ istanbul-lib-report (indirect, 3.0.0 → 3.0.1) · Repo · Changelog

Release Notes

3.0.1 (from changelog)

Bug Fixes

Does any of this look wrong? Please let us know.

↗️ istanbul-lib-source-maps (indirect, 4.0.1 → 5.0.6) · Repo · Changelog

Release Notes

5.0.6 (from changelog)

Bug Fixes

  • istanbul-lib-source-maps implicit else crash edge case (#789) (bbb5815)

5.0.5 (from changelog)

Bug Fixes

  • istanbul-lib-source-maps to preserve implicit else when sourcemaps are used (#706) (d16a155)

Does any of this look wrong? Please let us know.

↗️ istanbul-reports (indirect, 3.1.5 → 3.2.0) · Repo · Changelog

Release Notes

3.2.0 (from changelog)

Features

  • update HTML report filter to take a RegEx (#796) (a739999)

Bug Fixes

3.1.7 (from changelog)

Bug Fixes

  • ux: address bug with firefox event handling (2207a87)

3.1.6 (from changelog)

Bug Fixes

  • clover: always close last open tag (07c6ea6)

Does any of this look wrong? Please let us know.

↗️ jest-changed-files (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

30.5.0

On a personal note: King Harald V of Norway passed away this morning. He ascended the throne 35 years ago, two months before I was born. This release is dedicated to his memory. Hvil i fred 🇳🇴


This is a big release. It touches jest-runtime, jest-resolve and jest-haste-map in many places, and with this many changes there might be regressions 😬. If your suite behaves differently after upgrading, please open an issue.

Highlights

whenCalledWith

Mock functions can now configure return values per argument list, contributed by @timkindberg (#16053):

const fn = jest.fn();
fn.whenCalledWith('apple').mockReturnValue('red');
fn.whenCalledWith('banana').mockReturnValue('yellow');
fn.whenCalledWith(expect.any(Number)).mockReturnValue('numeric');

fn('apple'); // 'red'
fn('banana'); // 'yellow'
fn(42); // 'numeric'
fn('grape'); // undefined

The returned object is a real Mock, so mockReturnValueOnce, mockResolvedValue, mockImplementation etc. all chain here too. Argument slots accept literals or any asymmetric matcher, with the same equality semantics as toHaveBeenCalledWith(). Calls that match nothing fall through to the base mock. See the Mock Functions docs for matching and precedence details.

Describe-level retries

jest.retryTimes() can now retry a whole describe block instead of a single test, contributed by @soltonigiri (#16322). Each attempt reruns the block's beforeAll/afterAll hooks, child tests and nested describes, which helps when tests in a block depend on shared state:

describe('workflow', () => {
  jest.retryTimes(3, {entireDescribe: true});

  test('first step', () => {});
  test('second step', () => {}); // a failure retries the entire block
});

New file watcher

The non-watchman path of jest-haste-map is rewritten. @parcel/watcher replaces the homegrown NodeWatcher and FSEventsWatcher (#16188), and fdir replaces the hand-rolled directory recursion in the crawler (#16187). A batch of fixes also makes watching and indexing survive locked files on Windows, watchman failures, and duplicate manual mocks (#16295, #16358, #16355, #16360).

If you can, please run your suite with --no-watchman (in and out of watch mode) to exercise the new crawler and watchers, and report anything odd 👍

Long-requested dependency updates

  • babel-plugin-istanbul is updated to v8 (#16049)
  • glob is updated to v13 (#16397)
  • source-map-support is replaced with an implementation in @jest/source-map (#16327). This fixes a memory leak where source-map-support's process-global caches pinned every finished test file's sandbox. Source maps also survive environment teardown, --testLocationInResults looks up the right column, and scheme-prefixed sources like webpack:/// are kept as-is.

Performance

  • Warm module resolution costs about a third of what it did, and repeated work is gone from the resolution hot path (#16373, #16371).
  • Per-require overhead in jest-runtime is cut: module ID resolution is skipped when no mock can apply, and core modules answer before the manual-mock probe (#16376).
  • jest-snapshot loads babel, semver and synckit lazily, so every test process loads ~200 fewer modules (#16387).
  • jest-haste-map caches the watchman socket path, so warm runs spawn no watchman processes (#16386), and reuses cached metadata for duplicated haste names instead of re-parsing them on every startup (#16351).

More new APIs

  • Snapshot failures expose the .snap file path as matcherResult.snapshotPath in failureDetails (#16374).
  • --collectTests expands test.each/describe.each cases and reports per-status counts plus a summary line that matches a real run (#16259).
  • AggregateError inner errors and nested cause chains render with code frames and per-level indentation, and are included in --json output, retryReasons and reporter annotations (#16316).

ESM

A long list of fixes brings jest-runtime's module system closer to Node's:

  • Automocking and manual __mocks__ files now apply to ESM on Node 24.9+. Static imports, dynamic import() and require() of an ESM file generate an automock from the real module's namespace instead of failing with "Attempting to import a mock without a factory" (#16391).
  • Many jest.unstable_mockModule gaps are closed: mocks apply when the mocked file is require()d directly, async factories run once and fail the import instead of crashing the worker 😅, and mocks made inside jest.isolateModules stay scoped to that block (#16389, #16365).
  • require(esm), CJS/ESM interop, import.meta, data: URIs and error ordering now match Node in dozens of edge cases. See the Fixes section for the full list (#16364 through #16391).
  • The module-sync export condition resolves, so packages that expose their ESM entry point for require() load the same file Node picks (#16336).

The intentional divergences from Node's module system are now documented on the ECMAScript Modules page (#16368).

Resolver

  • The default resolver honors Node's --preserve-symlinks / NODE_PRESERVE_SYMLINKS (#16260).
  • moduleNameMapper applies to both spellings of core module specifiers (fs and node:fs), and builtins that only exist prefixed (node:sqlite, node:test) resolve asynchronously (#16390, #16388).
  • A user resolver can be written as an ES module (#16332).

On top of the highlights there are ~60 fixes across jest-circus, jest-haste-map, jest-config, jest-mock and the transform cache keys. See the full changelog below 😀


Features

  • [@jest/expect-utils, jest-mock] Add mockFn.whenCalledWith(...args) for configuring return values per argument list, with first-class asymmetric-matcher support (#16053)
  • [@jest/expect-utils] Export AsymmetricMatcher and FunctionParameters types (previously private to expect) (#16053)
  • [jest-circus, jest-core, jest-jasmine2, jest-test-result, jest-types] --collectTests now expands test.each/describe.each cases and reports per-status counts (skipped/todo via the new wouldRun flag for selected tests) plus a summary line that match a real run, including under --testNamePattern and .only/fdescribe focus on both the circus and jasmine2 runners (#16259)
  • [jest-circus, jest-environment, jest-runtime, jest-types] Add describe-level retries via jest.retryTimes(..., {entireDescribe: true}) (#16322)
  • [jest-circus, jest-message-util, jest-reporters, jest-types] Add retryMessages to AssertionResult and export formatErrorStack, so the retry log renders nested cause and AggregateError sections with code frames instead of serialized [cause]:/[errors]: markers (#16316)
  • [jest-circus, jest-types] Add unhandledErrorsDetailed to Circus.RunResult, so an unhandled rejection reports its cause chain and AggregateError entries with code frames instead of a pre-serialized stack (#16316)
  • [jest-haste-map] Replace NodeWatcher and FSEventsWatcher with @parcel/watcher for the non-watchman watch path (#16188)
  • [jest-resolve] Bump unrs-resolver to 1.12.1, remove jest-pnp-resolver and unnecessary checks (#15721)
  • [jest-resolve] Honor Node's --preserve-symlinks / NODE_PRESERVE_SYMLINKS in the default resolver by passing symlinks: false to unrs-resolver (#16260)
  • [jest-runtime] Apply automocking and manual __mocks__ files to synchronously evaluable ESM graphs on Node 24.9+ - static imports, dynamic import() and require() of an ESM file now generate an automock from the real module's namespace instead of failing with "Attempting to import a mock without a factory". Graphs that need async evaluation (top-level await) or an async-only resolver or transformer still throw (#16391)
  • [jest-runtime] Route process.getBuiltinModule through the sandbox, so it returns the sandbox process and the hooked node:module instead of the host's (#16391)
  • [jest-runtime] Throw an actionable error from module.register() and module.registerHooks() inside a test - the hooks attached to the loader running Jest itself, never saw the sandboxed requires they were meant for, and stayed registered for every later test file in the worker (#16391)
  • [jest-runtime] Surface resolution and import-attribute errors in an ESM graph before executing any of its CJS dependencies on Node 24.9+, matching Node's run-nothing-on-a-broken-graph behavior; the legacy loader on older versions keeps its linking-time execution order (#16391)
  • [jest-runtime] Throw ERR_SOURCE_PHASE_NOT_DEFINED with an actionable message for import source and import.source(), instead of failing at instantiation with V8's bare "Source phase import object is not defined" (#16391)
  • [jest-runtime] Emit the JSON-without-import-attribute deprecation warning once per test file instead of once per worker, so it is no longer silently swallowed for every file after the first (#16391)
  • [jest-runtime] Set import.meta.main to true in the test file and false in every module it loads, matching Node 24+ (#16367)
  • [jest-runtime] Resolve the module-sync export condition, so a package that exposes its ESM entry point for require() loads the same file Node would (#16336)
  • [jest-snapshot] Add external snapshot paths to custom reporter failure details (#16374)

Fixes

  • [jest-console, jest-reporters] CustomConsole now buffers console output so TestResult.console is populated for reporters when verbose is enabled, while GitHubActionsReporter avoids replaying buffered output in verbose mode (#16155)
  • [expect, jest-message-util, jest-pattern, jest-regex-util, jest-util] Revert node: protocol imports to restore webpack/browser-bundle compatibility (#16167)
  • [expect] Widen toMatchObject and objectContaining parameter type from Record<string, unknown> to object so class instances are accepted (#16196)
  • [jest-circus] Call a generator test body with the shared test context, so this matches what a regular test function receives (#16347)
  • [jest-circus] Capture the error listeners of the parent process instead of the in-sandbox process, so listeners registered before the test file survive teardown and sandbox listeners no longer leak onto the parent (#16347)
  • [jest-circus] Clear currentlyRunningTest after skipped and todo tests (#16342)
  • [jest-circus] Prevent late done() callbacks from affecting later test or hook invocations (#16343)
  • [jest-circus, jest-jasmine2] Honor --expand when formatting node:assert failures, instead of always collapsing the diff (#16347)
  • [jest-circus, jest-jasmine2, jest-message-util] Serialize the inner errors of an AggregateError into failureMessages, retryReasons and unhandledErrors, so --json output and reporter annotations include them (#16316)
  • [jest-circus, jest-snapshot] Keep snapshot state and counts correct when a test retries (#16344)
  • [@jest/create-cache-key-function] Include the caller support flags in the generated key, so a transformer that emits ESM or CJS based on them no longer shares one cache entry between the two (#16331)
  • [@jest/create-cache-key-function] Include the stringified project config in the generated key, so editing a transformer's own settings invalidates what it cached (#16331)
  • [@jest/transform] Include the caller support flags in a transform's cache key, so a file transformed both as ESM and as CJS no longer serves one shape's output for the other (#16331)
  • [jest-config] Add missing findRelatedTests, outputFile, and replname entries to ValidConfig so they no longer trigger spurious "Unknown option" warnings (#16224)
  • [jest-config] Use --config for the global config when multiple --projects are specified (#16273)
  • [jest-core] Serialize bigint values in --json and --outputFile output as their literal form (4n), instead of failing the run with TypeError: Do not know how to serialize a BigInt (#16338)
  • [jest-core] Do not report a CustomGC async resource (used by N-API addons such as napi-rs for per-isolate GC bookkeeping) as an open handle, since it is napi_unref'd by the addon and can never keep the event loop alive (#16379)
  • [jest-each] Keep a $&, $`, $' or $$ inside a %p param value out of the replacement, so the title shows the value instead of the text around it (#16338)
  • [jest-each] Interpolate a bigint into a %j title as its literal form ("4n") at any depth, instead of throwing TypeError: Do not know how to serialize a BigInt while collecting the tests (#16338)
  • [jest-environment, jest-runtime] Bind sandboxInjectedGlobals to the right values when injectGlobals is false, instead of shifting every one of them by a position (#16377)
  • [jest-environment-node, jest-util] Only warn about a conflicting globalsCleanup mode when one was explicitly configured, and follow the mode that is actually in effect (#16323)
  • [jest-environment-node, jest-util] Stop resolving lazy globals when setting up an environment, so Node 26's builtin module globals are no longer loaded (and no longer emit their deprecation warnings) for every test file (#16324)
  • [jest-haste-map] Keep watch mode alive when an outside process briefly makes a file unreadable on Windows, instead of tearing the watcher down on EPERM (#16295)
  • [jest-haste-map] Keep indexing when an outside process holds a file open on Windows, instead of failing the whole crawl on EPERM (#16358)
  • [jest-haste-map] Keep a duplicated manual mock resolving when the file it pointed at is deleted in watch mode (#16360)
  • [jest-haste-map] Shut the worker farm down when a duplicate manual mock aborts the build under throwOnModuleCollision (#16354)
  • [jest-haste-map] Attach the watchman client's error listener before the first command, so a watchman failure falls back to the node crawler instead of crashing on an unhandled error event, and always end the client (#16355)
  • [jest-haste-map] Stop delivering watch events after WatchmanWatcher is closed, and route its warnings through the configured console (#16355)
  • [jest-haste-map] Restore the nested duplicates index correctly in ModuleMap.fromJSON, so a haste collision reported inside a test worker raises DuplicateHasteCandidatesError instead of a TypeError (#16353)
  • [jest-haste-map] Match watched files on a full extension, so moduleFileExtensions: ['js'] no longer accepts foo.mjs (#16352)
  • [jest-haste-map] Delimit the fields that make up the haste map cache key, so two different option sets cannot hash to the same cache file (#16352)
  • [jest-message-util] Print the inner errors of an AggregateError thrown inside a test (#16316)
  • [jest-message-util] Indent nested cause and AggregateError sections of a test failure by one level per depth, so the nesting is legible instead of rendering flat (#16316)
  • [jest-message-util] Color stack traces line by line so blank lines stay blank (#16316)
  • [jest-message-util] Detect Jest's own frames without assuming the checkout directory's name, and cover @jest/* packages, so stack traces and code frames point at user code (#16326)
  • [jest-mock] mockResolvedValue / mockRejectedValue now see all overload return types, so a Promise-returning overload survives even when a later overload returns a non-Promise (e.g. pg.Client['end']) (#16237)
  • [@jest-environment/jsdom-abstract] Make @types/jsdom a peer dependency (#16166)
  • [jest-mock] Remove the leftover own accessor descriptor when restoring a spyOn of an inherited getter or setter, so the instance keeps reflecting the prototype (#16226)
  • [jest-resolve] Include extensionsToTreatAsEsm in the shouldLoadAsEsm cache key, so projects with different extension lists don't read each other's answers (#16369)
  • [jest-resolve] Make getModuleIDAsync build and cache data: URI module IDs the same way as getModuleID (#16370)
  • [jest-resolve] Keep the node: prefix when resolving a core module asynchronously, so a builtin that only exists prefixed (node:sea, node:sqlite, node:test, node:test/reporters) resolves instead of failing as a missing bare package (#16388)
  • [jest-resolve] Look up manual mocks for node: protocol specifiers under the unprefixed name they are stored as (#16388)
  • [jest-resolve] Apply moduleNameMapper consistently to both spellings of core module specifiers (fs vs node:fs) (#16390)
  • [jest-resolve] Keep virtual and ordinary mock module IDs isolated across test files (#16296)
  • [jest-resolve] Guard missing require.resolve.paths (#16052)
  • [jest-resolve, jest-config, jest-runner] Support a user resolver written as an ES module (#16332)
  • [jest-resolve, jest-runtime] Throw the CJS parse error for ESM syntax in a "type": "commonjs" package or a .cjs file instead of loading it as ESM, matching Node (#16368)
  • [@jest/source-map] Keep source map sources that name a scheme, such as webpack:///, instead of resolving them into a path that does not exist (#16327)
  • [@jest/source-map] Look up --testLocationInResults positions at the right column, and keep a mapping to the first column instead of discarding it (#16327)
  • [@jest/source-map] Warn when a source map cannot be parsed, instead of silently leaving its frames untranslated (#16327)
  • [jest-runner, @jest/source-map] Keep a source-mapped stack for an error thrown after the test environment was torn down (#16327)
  • [jest-runtime, @jest/source-map] Keep source maps past teardown and past the next test file's install, so a stack from a file no earlier stack mentioned still points at the original source (#16330)
  • [jest-runtime] Report that no coverage was collected when getAllV8CoverageInfoCopy is called after teardown, instead of returning an empty result (#16385)
  • [jest-runtime] Cache a CJS module's parsed exports before walking its re-exports, so two modules that re-export each other no longer overflow the stack when imported from ESM (#16363)
  • [jest-runtime] Keep a re-exported ES module's parse failure from marking the re-exporting CommonJS file as ESM, so module.exports = require('./dep.mjs') loads instead of failing with module is not defined (#16363)
  • [jest-runtime] Scope module mocks instantiated inside jest.isolateModules/isolateModulesAsync to that block, so a mock first imported there no longer outlives it - matching how CommonJS mocks already behave (#16365)
  • [jest-runtime] Suspend module isolation while generating an automock, so loading the real module to read its shape no longer populates the isolated registry (#16365)
  • [jest-runtime] Check a cached ES module's status before require() returns it, so a module whose evaluation threw rethrows that error and one left linked by a failed sibling is evaluated instead of returning uninitialized bindings (#16364)
  • [jest-runtime] Report the original ERR_REQUIRE_ASYNC_MODULE when a require() of a top-level-await graph is retried, instead of a spurious "concurrent import()" error (#16364)
  • [jest-runtime] Throw the evaluation error when another caller's import() of the same module failed while we awaited it, instead of resolving with the errored module (#16364)
  • [jest-runtime] Mark the result of require()ing an ES module that has a default export with __esModule: true through a live-binding facade, and serve the same object from require.cache, matching Node (#16367)
  • [jest-runtime] Provide a CommonJS module's exports under the 'module.exports' named export when imported from ESM, matching Node 23+ (#16367)
  • [jest-runtime] Give the test file itself a non-null require.main (#16367)
  • [jest-runtime] Populate module.children with the modules a file loads, matching Node (#16368)
  • [jest-runtime] Provide import.meta.resolve and import.meta.jest in data: URI modules, accept any-case mediatype parameters, and use Node's error codes for invalid data: URIs (#16368)
  • [jest-runtime] Key ES modules by full URL, so query and fragment suffixes create the same module instances as Node and show up in import.meta.url (#16375)
  • [jest-runtime] Share modules between overlapping graphs when a CommonJS module require()s an ES module mid-load, instead of evaluating shared dependencies twice (#16375)
  • [jest-runtime] Throw ERR_REQUIRE_CYCLE_MODULE like Node when a CommonJS module require()s an ES module that is still being loaded, instead of evaluating the module a second time (#16366)
  • [jest-runtime] Key builtin modules in the ESM registry by one canonical specifier (#16341)
  • [jest-runtime] import.meta.resolve() for a builtin uses its node: specifier (#16341)
  • [jest-runtime] Fall back to native ESM when a .js file contains ESM syntax but has no "type":"module" marker (#16152)
  • [jest-runtime] Allow require() of ESM-marked files on Node < 24.9 via transform fallback (#16244)
  • [jest-runtime, @jest/transform] Surface actionable ERR_REQUIRE_ESM error for files with untransformed ESM syntax instead of the generic "unexpected token" message (#16244)
  • [jest-runtime] Support older test environments whose moduleMocker does not implement clearMocksOnScope (#16169)
  • [jest-runtime] Apply jest.unstable_mockModule when the mocked file itself is require()d, not only when it is imported as a dependency (#16389)
  • [jest-runtime] Apply jest.unstable_mockModule to statically imported data: URIs on Node 24.9+, matching dynamic import() (#16389)
  • [jest-runtime] Run an async jest.unstable_mockModule factory once per module instead of twice, and fail the import instead of crashing the worker when the factory rejects (#16389)
  • [jest-runtime] Hide a require(esm) module that failed to evaluate from require.cache, as Node does, instead of exposing a namespace with uninitialized bindings (#16389)
  • [jest-runtime] Strip the byte-order mark when importing a JSON module, matching require() and Node (#16389)
  • [jest-runtime] Throw ERR_REQUIRE_ASYNC_MODULE when require(esm) runs under an async-only custom resolver, instead of silently resolving with the default resolver (#16389)
  • [jest-runtime] Parse imported JSON modules with the test realm's JSON, so their objects pass instanceof Object inside the test like require()d JSON does (#16389)
  • [jest-runtime] Accept every file: URL string in the sandboxed module.createRequire, including one with a localhost authority, as Node does (#16389)
  • [jest-runtime] Point at {virtual: true} when jest.mock or jest.unstable_mockModule is given a module that cannot be resolved (#16389)
  • [jest-reporters] Fix coverage report table formatting in CI/GitHub Actions environments where process.stdout.columns is undefined by falling back to the COLUMNS env var or 80 columns in CI, preserving existing behaviour in other non-TTY environments (#16227)
  • [jest-runtime] Support CJS-in-ESM exports via "module.exports" named exports (#16277)
  • [jest-snapshot] Keep a skipped or failed test's hinted snapshots, instead of reporting them obsolete (#16348)
  • [jest-util] Stop globsToMatcher reusing a cached matcher compiled with different picomatch options, and keep its dot: true default when dot is passed as undefined (#16381)
  • [pretty-format] Move the react-is aliases into the @jest scope, so they cannot be shadowed by unrelated packages published under the alias names (#16333)

Chore & Maintenance

  • [docs] Document the intentional divergences from Node's module system in the ECMAScript Modules page (#16368)
  • [docs] Note deprecation of react-test-renderer in React Native tutorial and pretty-format README (#16294)
  • [docs] Use @testing-library/react-native in the React Native tutorial instead of the deprecated react-test-renderer (#16318)
  • [babel-jest, @jest/transform] Update babel-plugin-istanbul to v8 (#16049)
  • [jest-config, @jest/reporters, jest-runtime] Update glob to v13 (#16397)
  • [jest-haste-map] Refactor massive class into multiple files (#16180)
  • [jest-haste-map] Drop walker dependency; replace hand-rolled directory recursion in the JS crawler and watcher startup with fdir (#16187)
  • [jest-haste-map] Reuse cached metadata for files whose haste name is a known duplicate, instead of re-reading and re-parsing them on every startup (#16351)
  • [jest-haste-map] Cache the watchman socket path and replace the watchman --version probe with get-sockname, so warm runs spawn no watchman processes (#16386)
  • [jest-resolve] Store the per-directory package-type lookup in the cache it reads, so it actually memoizes (#16369)
  • [jest-resolve, jest-runtime] Cut repeated work on the resolution hot path: hoist the platform-extension list to construction, memoize isCoreModule and the options cache-key serialization, skip mapper preparation when no moduleNameMapper is configured, run each mapper regex once, and stop re-parsing NODE_OPTIONS on every default-resolver call (#16371)
  • [jest-resolve] Cut warm resolution cost to about a third: reuse one unrs-resolver factory per options shape instead of cloning per resolution, compose the factory cache key from per-array cached strings instead of serializing options, and stop constructing an Error for misses that findNodeModule swallows; add a __benchmarks__ suite for the default resolver (#16373)
  • [jest-runner, @jest/source-map] Replace source-map-support with an implementation in @jest/source-map (#16327)
  • [jest-snapshot] Load babel, semver and synckit lazily, so requiring the package (which every test process does through @jest/expect) no longer loads ~200 modules that only writing inline snapshots needs (#16387)
  • [jest-runtime] Reduce per-require overhead: skip module ID resolution when no mock can apply, answer core modules before probing for a manual mock, share one require.cache proxy across modules, and cache empty files (#16376)
  • [@jest/source-map] Deprecate getCallsite in favour of SourceMapSupport#getCallsite (#16327)
  • [jest-runtime] Avoid magical null value in ESM loader (#16160)

New Contributors

Full Changelog: v30.4.2...v30.5.0

30.4.1

Features

  • [jest-config, jest-core, jest-runner, jest-schemas, jest-types] Allow custom runner configuration options via tuple format ['runner-path', {options}] (#16141)

Fixes

  • [jest-runtime] Align CJS-from-ESM default export with Node: module.exports is always the ESM default, __esModule unwrapping is no longer applied (#16143)

Full Changelog: v30.4.0...v30.4.1

30.4.0

Big release! 😀

Main feature is a rewrite of our custom runtime in preparation for stabilisation of native support of ESM. As part of that work require(esm) module is now supported on Node 24.9+ (still requires --experimental-vm-modules like before).

In addition we now support fake timers for the recently released Temporal API in Node v26.

React 19 is also supported properly in pretty-format, meaning snapshots of React components now work like they should.

Due to all the changes, there might be regressions that snuck in. Please report them!

Full list of changes below

Features

  • [babel-jest] Support collecting coverage from .mts, .cts (and other) files (#15994)
  • [jest-circus, jest-cli, jest-config, jest-core, jest-jasmine2, jest-types] Add --collect-tests flag to discover and list tests without executing them (#16006)
  • [jest-config, jest-runner, jest-worker] Add workerGracefulExitTimeout config option to control how long workers are given to exit before being force-killed (#15984)
  • [jest-config] Add support for jest.config.mts as a valid configuration file (#16005)
  • [jest-config, jest-core, jest-reporters, jest-runner] verbose and silent can now be set per-project; the project-level value overrides the global value for that project's tests (#16133)
  • [@jest/fake-timers] Accept Temporal.Duration in jest.advanceTimersByTime() and jest.advanceTimersByTimeAsync() (#16128)
  • [@jest/fake-timers] Accept Temporal.Instant and Temporal.ZonedDateTime in jest.setSystemTime() and useFakeTimers({now}) (#16128)
  • [@jest/fake-timers] Support faking Temporal.Now.* (#16131)
  • [jest-mock] Add clearMocksOnScope(scope) on ModuleMocker for clearing every mock function exposed on a scope object (#16088)
  • [jest-resolve] Add canResolveSync() on Resolver so callers can detect when a user-configured resolver only exports an async hook (#16064)
  • [jest-runtime] Use synchronous evaluate() for ES modules without top-level await on Node versions that support it (v24.9+), and prefer the synchronous transform path when a sync transformer is configured (#16062)
  • [jest-runtime] Support require() of ES modules on Node v24.9+ (#16074)
  • [jest-runtime] Validate TC39 import attributes (with { type: 'json' }) on ESM imports (#16127)
  • [@jest/transform] Add canTransformSync(filename) on ScriptTransformer so callers can pick the sync vs async transform path (#16062)
  • [jest-util] Add isError helper (#16076)
  • [pretty-format] Support React 19 (#16123)

Fixes

  • [expect-utils] Fix toStrictEqual failing on structuredClone results due to cross-realm constructor mismatch (#15959)
  • [@jest/expect-utils] Prevent toMatchObject/subset matching from throwing when encountering exotic iterables (#15952)
  • [fake-timers] Convert Date to milliseconds before passing to @sinonjs/fake-timers (#16029)
  • [jest] Export GlobalConfig and ProjectConfig TypeScript types (#16132)
  • [jest-circus] Prevent crash when asyncError is undefined for non-Error throws (#16003)
  • [jest-circus, jest-jasmine2] Include Error.cause in JSON failureMessages output (#15967)
  • [jest-config] Fix preset path resolution on Windows when the preset uses subpath exports (#15961)
  • [jest-config] Allow collectCoverage and coverageProvider in project config without a validation warning (#16132)
  • [jest-config] Project config validator now emits "is not supported in an individual project configuration" instead of "probably a typing mistake" for known global-only options (#16132)
  • [jest-environment-node] Fix --localstorage-file warning on Node 25+ (#16086)
  • [jest-reporters] Apply global coverage threshold to unmatched pattern files in addition to glob/path thresholds (#16137)
  • [jest-reporters, jest-runner, jest-runtime, jest-transform] Fix coverage report not showing correct code coverage when using projects config option (#16140)
  • [jest-runtime] Resolve expect and @jest/expect from the internal module registry so test-file imports share the same JestAssertionError as the global expect (#16130)
  • [jest-runtime] Improve CJS-from-ESM interop: __esModule/Babel default unwrap, broader named-export coverage, and shared CJS singleton across importers (#16050)
  • [jest-runtime] Load .js files with ESM syntax but no "type":"module" marker as native ESM (#16050)
  • [jest-runtime] Extend the .js-with-ESM-syntax fallback to require() on Node v24.9+ - falls back to require(esm) when the CJS parser rejects ESM syntax (#16078)
  • [jest-runtime] Fix deadlocks and double-evaluation in concurrent ESM and wasm imports (#16050)
  • [jest-runtime] Fix error when require() is called after the Jest environment has been torn down (#15951)
  • [jest-runtime] Fix missing error when import() is called after the Jest environment has been torn down (#16080)
  • [jest-runtime] Fix virtual unstable_mockModule registrations not respected in ESM (#16081)
  • [jest-runtime] Apply moduleNameMapper when resolving modules with require.resolve() and the paths option (#16135)

Chore & Maintenance

  • [@jest/fake-timers] Upgrade @sinonjs/fake-timers (#16139)
  • [jest-runtime] Use synchronous linkRequests / instantiate for ESM linking on Node v24.9+ (#16063)

New Contributors

Full Changelog: v30.3.0...v30.4.0

30.3.0

Features

  • [jest-config] Add defineConfig and mergeConfig helpers for type-safe Jest config (#15844)
  • [jest-fake-timers] Add setTimerTickMode to configure how timers advance
  • [*] Reduce token usage when run through LLMs (3f17932)

Fixes

  • [jest-config] Keep CLI coverage output when using --json with --outputFile (#15918)
  • [jest-mock] Use Symbol from test environment (#15858)
  • [jest-reporters] Fix issue where console output not displayed for GHA reporter even with silent: false option (#15864)
  • [jest-runtime] Fix issue where user cannot utilize dynamic import despite specifying --experimental-vm-modules Node option (#15842)
  • [jest-test-sequencer] Fix issue where failed tests due to compilation errors not getting re-executed even with --onlyFailures CLI option (#15851)
  • [jest-util] Make sure process.features.require_module is false (#15867)

Chore & Maintenance

  • [*] Replace remaining micromatch uses with picomatch
  • [deps] Update to sinon/fake-timers v15
  • [docs] Update V30 migration guide to notify users on jest.mock() work with case-sensitive path (#15849)
  • Updated Twitter icon to match the latest brand guidelines (#15869)

30.2.0

Chore & Maintenance

  • [*] Update example repo for testing React Native projects (#15832)
  • [*] Update jest-watch-typeahead to v3 (#15830)

Features

  • [jest-environment-jsdom-abstract] Add support for JSDOM v27 (#15834)

Fixes

  • [babel-jest] Export the TransformerConfig interface (#15820)
  • [jest-config] Fix jest.config.ts with TS loader specified in docblock pragma (#15839)

30.0.5 (from changelog)

Features

  • [jest-config] Allow testMatch to take a string value
  • [jest-worker] Let workerIdleMemoryLimit accept 0 to always restart worker child processes

Fixes

  • [expect] Fix bigint error (#15702)

30.0.2

What's Changed

Fixes

  • [jest-matcher-utils] Make 'deepCyclicCopyObject' safer by setting descriptors to a null-prototype object (#15689)
  • [jest-util] Make garbage collection protection property writable (#15689)

Full Changelog: https://github.com/jestjs/jest/blob/main/CHANGELOG.md

30.0.1

What's Changed

Features

  • [jest-resolver] Implement the defaultAsyncResolver (#15679)

Fixes

  • [jest-resolver] Resolve builtin modules correctly (#15683)
  • [jest-environment-node, jest-util] Avoid setting globals cleanup protection symbol when feature is off (#15684)

Chore & Maintenance

  • [*] Remove and deprecate jest-repl package (#15673)
  • [jest-resolver] Replace custom isBuiltinModule with node's isBuiltin (#15685)

New Contributors

Full Changelog: https://github.com/jestjs/jest/blob/main/CHANGELOG.md

30.0.0

Today we are happy to announce the release of Jest 30. This release features a substantial number of changes, fixes, and improvements. While it is one of the largest major releases of Jest ever, we admit that three years for a major release is too long. In the future, we are aiming to make more frequent major releases to keep Jest great for the next decade.

If you want to skip all the news and just get going, run npm install jest@^30.0.0 and follow the migration guide: Upgrading from Jest 29 to 30.

Read the full blog post

Features

  • [*] Renamed globalsCleanupMode to globalsCleanup and --waitNextEventLoopTurnForUnhandledRejectionEvents to --waitForUnhandledRejections
  • [expect] Add ArrayOf asymmetric matcher for validating array elements. (#15567)
  • [babel-jest] Add option excludeJestPreset to allow opting out of babel-preset-jest (#15164)
  • [expect] Revert #15038 to fix expect(fn).toHaveBeenCalledWith(expect.objectContaining(...)) when there are multiple calls (#15508)
  • [jest-circus, jest-cli, jest-config] Add waitNextEventLoopTurnForUnhandledRejectionEvents flag to minimise performance impact of correct detection of unhandled promise rejections introduced in #14315 (#14681)
  • [jest-circus] Add a waitBeforeRetry option to jest.retryTimes (#14738)
  • [jest-circus] Add a retryImmediately option to jest.retryTimes (#14696)
  • [jest-circus, jest-jasmine2] Allow setupFilesAfterEnv to export an async function (#10962)
  • [jest-circus, jest-test-result] Add startedAt timestamp in TestCaseResultObject within onTestCaseResult (#15145)
  • [jest-cli] Export buildArgv (#15310)
  • [jest-config] [BREAKING] Add mts and cts to default moduleFileExtensions config (#14369)
  • [jest-config] [BREAKING] Update testMatch and testRegex default option for supporting mjs, cjs, mts, and cts (#14584)
  • [jest-config] Loads config file from provided path in package.json (#14044)
  • [jest-config] Allow loading jest.config.cts files (#14070)
  • [jest-config] Show rootDir in error message when a preset fails to load (#15194)
  • [jest-config] Support loading TS config files using esbuild-register via docblock loader (#15190)
  • [jest-config] Allow passing TS config loader options via docblock comment (#15234)
  • [jest-config] If Node is running with type stripping enabled, do not require a TS loader (#15480)
  • [@jest/core] Group together open handles with the same stack trace (#13417, & #14789)
  • [@jest/core] Add perfStats to surface test setup overhead (#14622)
  • [@jest/core] [BREAKING] Changed --filter to accept an object with shape { filtered: Array<string> } to match documentation (#13319)
  • [@jest/core] Support --outputFile option for --listTests (#14980)
  • [@jest/core] Stringify Errors properly with --json flag (#15329)
  • [@jest/core, @jest/test-sequencer] [BREAKING] Exposes globalConfig & contexts to TestSequencer (#14535, & #14543)
  • [jest-each] Introduce %$ option to add number of the test to its title (#14710)
  • [@jest/environment] [BREAKING] Remove deprecated jest.genMockFromModule() (#15042)
  • [@jest/environment] [BREAKING] Remove unnecessary defensive code (#15045)
  • [jest-environment-jsdom] [BREAKING] Upgrade JSDOM to v22 (#13825)
  • [@jest/environment-jsdom-abstract] Introduce new package which abstracts over the jsdom environment, allowing usage of custom versions of JSDOM (#14717)
  • [jest-environment-node] Update jest environment with dispose symbols Symbol (#14888 & #14909)
  • [expect, @jest/expect] [BREAKING] Add type inference for function parameters in CalledWith assertions (#15129)
  • [@jest/expect-utils] Properly compare all types of TypedArrays (#15178)
  • [@jest/fake-timers] [BREAKING] Upgrade @sinonjs/fake-timers to v13 (#14544 & #15470)
  • [@jest/fake-timers] Exposing new modern timers function advanceTimersToFrame() which advances all timers by the needed milliseconds to execute callbacks currently scheduled with requestAnimationFrame (#14598)
  • [jest-matcher-utils] Add SERIALIZABLE_PROPERTIES to allow custom serialization of objects (#14893)
  • [jest-mock] Add support for the Explicit Resource Management proposal to use the using keyword with jest.spyOn(object, methodName) (#14895)
  • [jest-reporters] Add support for DEC mode 2026 (#15008)
  • [jest-resolver] Support file:// URLs as paths (#15154)
  • [jest-resolve,jest-runtime,jest-resolve-dependencies] Pass the conditions when resolving stub modules (#15489)
  • [jest-runtime] Exposing new modern timers function jest.advanceTimersToFrame() from @jest/fake-timers (#14598)
  • [jest-runtime] Support import.meta.filename and import.meta.dirname (available from Node 20.11) (#14854)
  • [jest-runtime] Support import.meta.resolve (#14930)
  • [jest-runtime] [BREAKING] Make it mandatory to pass globalConfig to the Runtime constructor (#15044)
  • [jest-runtime] Add unstable_unmockModule (#15080)
  • [jest-runtime] Add onGenerateMock transformer callback for auto generated callbacks (#15433 & #15482)
  • [jest-runtime] [BREAKING] Use vm.compileFunction over vm.Script (#15461)
  • [@jest/schemas] Upgrade @sinclair/typebox to v0.34 (#15450)
  • [@jest/types] test.each(): Accept a readonly (as const) table properly (#14565)
  • [@jest/types] Improve argument type inference passed to test and describe callback functions from each tables (#14920)
  • [jest-snapshot] [BREAKING] Add support for Error causes in snapshots (#13965)
  • [jest-snapshot] Support Prettier 3 (#14566)
  • [@jest/util-snapshot] Extract utils used by tooling from jest-snapshot into its own package (#15095)
  • [pretty-format] [BREAKING] Do not render empty string children ('') in React plugin (#14470)

Fixes

  • [expect] Show AggregateError to display (#15346)
  • [*] Replace exit with exit-x (#15399)
  • [babel-plugin-jest-hoist] Use denylist instead of the deprecated blacklist for Babel 8 support (#14109)
  • [babel-plugin-jest-hoist] Do not rely on buggy Babel behaviour (#15415)
  • [expect] Check error instance type for toThrow/toThrowError (#14576)
  • [expect] Improve diff for failing expect.objectContaining (#15038)
  • [expect] Use Array.isArray to check if an array is an Array (#15101)
  • [expect] Fix Error cause assertion errors (#15339)
  • [jest-changed-files] Print underlying errors when VCS commands fail (#15052)
  • [jest-changed-files] Abort sl root call if output resembles a steam locomotive (#15053)
  • [jest-circus] [BREAKING] Prevent false test failures caused by promise rejections handled asynchronously (#14315)
  • [jest-circus] Replace recursive makeTestResults implementation with iterative one (#14760)
  • [jest-circus] Omit expect.hasAssertions() errors if a test already has errors (#14866)
  • [jest-circus, jest-expect, jest-snapshot] Pass test.failing tests when containing failing snapshot matchers (#14313)
  • [jest-circus] Concurrent tests now emit jest circus events at the correct point and in the expected order. (#15381)
  • [jest-cli] [BREAKING] Validate CLI flags that require arguments receives them (#14783)
  • [jest-config] Make sure to respect runInBand option (#14578)
  • [jest-config] Support testTimeout in project config (#14697)
  • [jest-config] Support coverageReporters in project config (#14697)
  • [jest-config] Allow reporters in project config (#14768)
  • [jest-config] Allow Node16/NodeNext/Bundler moduleResolution in project's tsconfig (#14739)
  • [@jest/create-cache-key-function] Correct the return type of createCacheKey (#15159)
  • [jest-each] Allow $keypath templates with null or undefined values (#14831)
  • [@jest/expect-utils] Fix comparison of DataView (#14408)
  • [@jest/expect-utils] [BREAKING] exclude non-enumerable in object matching (#14670)
  • [@jest/expect-utils] Fix comparison of URL (#14672)
  • [@jest/expect-utils] Check Symbol properties in equality (#14688)
  • [@jest/expect-utils] Catch circular references within arrays when matching objects (#14894)
  • [@jest/expect-utils] Fix not addressing to Sets and Maps as objects without keys (#14873)
  • [jest-haste-map] Fix errors or clobbering with multiple hasteImplModulePaths (#15522)
  • [jest-leak-detector] Make leak-detector more aggressive when running GC (#14526)
  • [jest-runtime] Properly handle re-exported native modules in ESM via CJS (#14589)
  • [jest-runtime] Refactor _importCoreModel so required core module is consistent if modified while loading (#15077)
  • [jest-schemas, jest-types] [BREAKING] Fix type of testFailureExitCode config option(#15232)
  • [jest-util] Make sure isInteractive works in a browser (#14552)
  • [pretty-format] [BREAKING] Print ArrayBuffer and DataView correctly (#14290)
  • [pretty-format] Fixed a bug where "anonymous custom elements" were not being printed as expected. (#15138)
  • [jest-cli] When specifying paths on the command line, only match against the relative paths of the test files (#12519)
    • [BREAKING] Changes testPathPattern configuration option to testPathPatterns, which now takes a list of patterns instead of the regex.
    • [BREAKING] --testPathPattern is now --testPathPatterns
    • [BREAKING] Specifying testPathPatterns when programmatically calling watch must be specified as new TestPathPatterns(patterns), where TestPathPatterns can be imported from @jest/pattern
  • [jest-reporters, jest-runner] Unhandled errors without stack get correctly logged to console (#14619)
  • [jest-util] Always load mjs files with import (#15447)
  • [jest-worker] Properly handle a circular reference error when worker tries to send an assertion fails where either the expected or actual value is circular (#15191)
  • [jest-worker] Properly handle a BigInt when worker tries to send an assertion fails where either the expected or actual value is BigInt (#15191)
  • [expect] Resolve issue where ObjectContaining matched non-object values. ([#15463])(#15463).
    • Adds a conditional/check to ensure the argument passed to expect is an object.
    • Add unit tests for new ObjectContaining behavior.
    • Remove invalid/wrong test case assertions for ObjectContaining.
  • [jest-worker] Addresses incorrect state on exit (#15610)

Performance

  • [*] [BREAKING] Bundle all of Jest's modules into index.js (#12348, #14550 & #14661)
  • [jest-haste-map] Only spawn one process to check for watchman installation (#14826)
  • [jest-runner] Better cleanup source-map-support after test to resolve (minor) memory leak (#15233)
  • [jest-circus, jest-environment-node, jest-repl, jest-runner, jest-util] Cleanup global variables on environment teardown to reduce memory leaks (#15215 & #15636 & #15643)

Chore & Maintenance

  • [jest-environment-jsdom, jest-environment-jsdom-abstract] Increased version of jsdom to ^26.0.0 (#15325CVE-2024-37890)
  • [*] Increase version of micromatch to ^4.0.7 (#15082)
  • [*] [BREAKING] Drop support for Node.js versions 14, 16, 19, 21 and 23 (#14460, #15118, #15623, #15640)
  • [*] [BREAKING] Drop support for typescript@4.3, minimum version is now 5.4 (#14542, #15621)
  • [*] Depend on exact versions of monorepo dependencies instead of ^ range (#14553)
  • [*] [BREAKING] Add ESM wrapper for all of Jest's modules (#14661)
  • [*] [BREAKING] Upgrade to glob@10 (#14509)
  • [*] Use TypeError over Error where appropriate (#14799)
  • [docs] Fix typos in CHANGELOG.md and packages/jest-validate/README.md (#14640)
  • [docs] Don't use alias matchers in docs (#14631)
  • [babel-jest, babel-preset-jest] [BREAKING] Increase peer dependency of @babel/core to ^7.11 (#14109)
  • [babel-jest, @jest/transform] Update babel-plugin-istanbul to v6 (#15156)
  • [babel-plugin-jest-hoist] Move unnecessary dependencies to devDependencies (#15010)
  • [expect] [BREAKING] Remove .toBeCalled(), .toBeCalledTimes(), .toBeCalledWith(), .lastCalledWith(), .nthCalledWith(), .toReturn(), .toReturnTimes(), .toReturnWith(), .lastReturnedWith(), .nthReturnedWith() and .toThrowError() matcher aliases (#14632)
  • [jest-cli, jest-config, @jest/types] [BREAKING] Remove deprecated --init argument (#14490)
  • [jest-config, @jest/core, jest-util] Upgrade ci-info (#14655)
  • [jest-mock] [BREAKING] Remove MockFunctionMetadataType, MockFunctionMetadata and SpyInstance types (#14621)
  • [@jest/reporters] Upgrade istanbul-lib-source-maps (#14924)
  • [jest-schemas] Upgrade @sinclair/typebox (#14775)
  • [jest-transform] Upgrade write-file-atomic (#14274)
  • [jest-util] Upgrade picomatch to v4 (#14653 & #14885)
  • [docs] Append to NODE_OPTIONS, not overwrite ([#14730](https://github.com/jestjs/jest/pull/14730))
  • [docs] Updated .toHaveBeenCalled() documentation to correctly reflect its functionality (#14842)
  • [docs] Link NestJS documentation on testing with Jest (#14940)
  • [docs] Revised documentation for .toHaveBeenCalled() to accurately depict its functionality. (#14853)
  • [docs] Removed ExpressJS reference link from documentation due to dead link (#15270)
  • [docs] Correct broken links in docs (#15359)

See the CHANGELOG.

29.7.0

Features

  • [create-jest] Add npm init / yarn create initialiser for Jest projects (#14465)
  • [jest-validate] Allow deprecation warnings for unknown options (#14499)

Fixes

  • [jest-resolver] Replace unmatched capture groups in moduleNameMapper with empty string instead of undefined (#14507)
  • [jest-snapshot] Allow for strings as well as template literals in inline snapshots (#14465)
  • [@jest/test-sequencer] Calculate test runtime if perStats.duration is missing (#14473)

Performance

  • [@jest/create-cache-key-function] Cache access of NODE_ENV and BABEL_ENV (#14455)

Chore & Maintenance

  • [jest-cli] Move internal config initialisation logic to the create-jest package (#14465)

New Contributors

Full Changelog: v29.6.4...v29.7.0

29.6.3

Fixes

  • [expect, @jest/expect-utils] ObjectContaining support symbol as key (#14414)
  • [expect] Remove @types/node from dependencies (#14385)
  • [jest-core] Use workers in watch mode by default to avoid crashes (#14059 & #14085).
  • [jest-reporters] Update istanbul-lib-instrument dependency to v6. (#14401)
  • [jest-mock] Revert #13692 as it was a breaking change (#14429)
  • [jest-mock] Revert #13866 as it was a breaking change (#14429)
  • [jest-mock] Revert #13867 as it was a breaking change (#14429)
  • [@jest/reporters] Marks Reporter's hooks as optional (#14433)
  • [jest-runtime] Fix dynamic ESM import module bug when loaded module through jest.isolateModulesAsync (#14397)

Chore & Maintenance

  • [jest-changed-files, jest-circus, jest-console, @jest/core, @jest/runtime, @jest/transform] Use invariant and notEmpty from jest-util rather than own internal (#14366)

New Contributors

Full Changelog: v29.6.2...v29.6.3

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ jest-circus (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ jest-cli (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ jest-config (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ jest-diff (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ jest-docblock (indirect, 28.1.1 → 30.5.0) · Repo · Changelog

Release Notes

30.5.0

On a personal note: King Harald V of Norway passed away this morning. He ascended the throne 35 years ago, two months before I was born. This release is dedicated to his memory. Hvil i fred 🇳🇴


This is a big release. It touches jest-runtime, jest-resolve and jest-haste-map in many places, and with this many changes there might be regressions 😬. If your suite behaves differently after upgrading, please open an issue.

Highlights

whenCalledWith

Mock functions can now configure return values per argument list, contributed by @timkindberg (#16053):

const fn = jest.fn();
fn.whenCalledWith('apple').mockReturnValue('red');
fn.whenCalledWith('banana').mockReturnValue('yellow');
fn.whenCalledWith(expect.any(Number)).mockReturnValue('numeric');

fn('apple'); // 'red'
fn('banana'); // 'yellow'
fn(42); // 'numeric'
fn('grape'); // undefined

The returned object is a real Mock, so mockReturnValueOnce, mockResolvedValue, mockImplementation etc. all chain here too. Argument slots accept literals or any asymmetric matcher, with the same equality semantics as toHaveBeenCalledWith(). Calls that match nothing fall through to the base mock. See the Mock Functions docs for matching and precedence details.

Describe-level retries

jest.retryTimes() can now retry a whole describe block instead of a single test, contributed by @soltonigiri (#16322). Each attempt reruns the block's beforeAll/afterAll hooks, child tests and nested describes, which helps when tests in a block depend on shared state:

describe('workflow', () => {
  jest.retryTimes(3, {entireDescribe: true});

  test('first step', () => {});
  test('second step', () => {}); // a failure retries the entire block
});

New file watcher

The non-watchman path of jest-haste-map is rewritten. @parcel/watcher replaces the homegrown NodeWatcher and FSEventsWatcher (#16188), and fdir replaces the hand-rolled directory recursion in the crawler (#16187). A batch of fixes also makes watching and indexing survive locked files on Windows, watchman failures, and duplicate manual mocks (#16295, #16358, #16355, #16360).

If you can, please run your suite with --no-watchman (in and out of watch mode) to exercise the new crawler and watchers, and report anything odd 👍

Long-requested dependency updates

  • babel-plugin-istanbul is updated to v8 (#16049)
  • glob is updated to v13 (#16397)
  • source-map-support is replaced with an implementation in @jest/source-map (#16327). This fixes a memory leak where source-map-support's process-global caches pinned every finished test file's sandbox. Source maps also survive environment teardown, --testLocationInResults looks up the right column, and scheme-prefixed sources like webpack:/// are kept as-is.

Performance

  • Warm module resolution costs about a third of what it did, and repeated work is gone from the resolution hot path (#16373, #16371).
  • Per-require overhead in jest-runtime is cut: module ID resolution is skipped when no mock can apply, and core modules answer before the manual-mock probe (#16376).
  • jest-snapshot loads babel, semver and synckit lazily, so every test process loads ~200 fewer modules (#16387).
  • jest-haste-map caches the watchman socket path, so warm runs spawn no watchman processes (#16386), and reuses cached metadata for duplicated haste names instead of re-parsing them on every startup (#16351).

More new APIs

  • Snapshot failures expose the .snap file path as matcherResult.snapshotPath in failureDetails (#16374).
  • --collectTests expands test.each/describe.each cases and reports per-status counts plus a summary line that matches a real run (#16259).
  • AggregateError inner errors and nested cause chains render with code frames and per-level indentation, and are included in --json output, retryReasons and reporter annotations (#16316).

ESM

A long list of fixes brings jest-runtime's module system closer to Node's:

  • Automocking and manual __mocks__ files now apply to ESM on Node 24.9+. Static imports, dynamic import() and require() of an ESM file generate an automock from the real module's namespace instead of failing with "Attempting to import a mock without a factory" (#16391).
  • Many jest.unstable_mockModule gaps are closed: mocks apply when the mocked file is require()d directly, async factories run once and fail the import instead of crashing the worker 😅, and mocks made inside jest.isolateModules stay scoped to that block (#16389, #16365).
  • require(esm), CJS/ESM interop, import.meta, data: URIs and error ordering now match Node in dozens of edge cases. See the Fixes section for the full list (#16364 through #16391).
  • The module-sync export condition resolves, so packages that expose their ESM entry point for require() load the same file Node picks (#16336).

The intentional divergences from Node's module system are now documented on the ECMAScript Modules page (#16368).

Resolver

  • The default resolver honors Node's --preserve-symlinks / NODE_PRESERVE_SYMLINKS (#16260).
  • moduleNameMapper applies to both spellings of core module specifiers (fs and node:fs), and builtins that only exist prefixed (node:sqlite, node:test) resolve asynchronously (#16390, #16388).
  • A user resolver can be written as an ES module (#16332).

On top of the highlights there are ~60 fixes across jest-circus, jest-haste-map, jest-config, jest-mock and the transform cache keys. See the full changelog below 😀


Features

  • [@jest/expect-utils, jest-mock] Add mockFn.whenCalledWith(...args) for configuring return values per argument list, with first-class asymmetric-matcher support (#16053)
  • [@jest/expect-utils] Export AsymmetricMatcher and FunctionParameters types (previously private to expect) (#16053)
  • [jest-circus, jest-core, jest-jasmine2, jest-test-result, jest-types] --collectTests now expands test.each/describe.each cases and reports per-status counts (skipped/todo via the new wouldRun flag for selected tests) plus a summary line that match a real run, including under --testNamePattern and .only/fdescribe focus on both the circus and jasmine2 runners (#16259)
  • [jest-circus, jest-environment, jest-runtime, jest-types] Add describe-level retries via jest.retryTimes(..., {entireDescribe: true}) (#16322)
  • [jest-circus, jest-message-util, jest-reporters, jest-types] Add retryMessages to AssertionResult and export formatErrorStack, so the retry log renders nested cause and AggregateError sections with code frames instead of serialized [cause]:/[errors]: markers (#16316)
  • [jest-circus, jest-types] Add unhandledErrorsDetailed to Circus.RunResult, so an unhandled rejection reports its cause chain and AggregateError entries with code frames instead of a pre-serialized stack (#16316)
  • [jest-haste-map] Replace NodeWatcher and FSEventsWatcher with @parcel/watcher for the non-watchman watch path (#16188)
  • [jest-resolve] Bump unrs-resolver to 1.12.1, remove jest-pnp-resolver and unnecessary checks (#15721)
  • [jest-resolve] Honor Node's --preserve-symlinks / NODE_PRESERVE_SYMLINKS in the default resolver by passing symlinks: false to unrs-resolver (#16260)
  • [jest-runtime] Apply automocking and manual __mocks__ files to synchronously evaluable ESM graphs on Node 24.9+ - static imports, dynamic import() and require() of an ESM file now generate an automock from the real module's namespace instead of failing with "Attempting to import a mock without a factory". Graphs that need async evaluation (top-level await) or an async-only resolver or transformer still throw (#16391)
  • [jest-runtime] Route process.getBuiltinModule through the sandbox, so it returns the sandbox process and the hooked node:module instead of the host's (#16391)
  • [jest-runtime] Throw an actionable error from module.register() and module.registerHooks() inside a test - the hooks attached to the loader running Jest itself, never saw the sandboxed requires they were meant for, and stayed registered for every later test file in the worker (#16391)
  • [jest-runtime] Surface resolution and import-attribute errors in an ESM graph before executing any of its CJS dependencies on Node 24.9+, matching Node's run-nothing-on-a-broken-graph behavior; the legacy loader on older versions keeps its linking-time execution order (#16391)
  • [jest-runtime] Throw ERR_SOURCE_PHASE_NOT_DEFINED with an actionable message for import source and import.source(), instead of failing at instantiation with V8's bare "Source phase import object is not defined" (#16391)
  • [jest-runtime] Emit the JSON-without-import-attribute deprecation warning once per test file instead of once per worker, so it is no longer silently swallowed for every file after the first (#16391)
  • [jest-runtime] Set import.meta.main to true in the test file and false in every module it loads, matching Node 24+ (#16367)
  • [jest-runtime] Resolve the module-sync export condition, so a package that exposes its ESM entry point for require() loads the same file Node would (#16336)
  • [jest-snapshot] Add external snapshot paths to custom reporter failure details (#16374)

Fixes

  • [jest-console, jest-reporters] CustomConsole now buffers console output so TestResult.console is populated for reporters when verbose is enabled, while GitHubActionsReporter avoids replaying buffered output in verbose mode (#16155)
  • [expect, jest-message-util, jest-pattern, jest-regex-util, jest-util] Revert node: protocol imports to restore webpack/browser-bundle compatibility (#16167)
  • [expect] Widen toMatchObject and objectContaining parameter type from Record<string, unknown> to object so class instances are accepted (#16196)
  • [jest-circus] Call a generator test body with the shared test context, so this matches what a regular test function receives (#16347)
  • [jest-circus] Capture the error listeners of the parent process instead of the in-sandbox process, so listeners registered before the test file survive teardown and sandbox listeners no longer leak onto the parent (#16347)
  • [jest-circus] Clear currentlyRunningTest after skipped and todo tests (#16342)
  • [jest-circus] Prevent late done() callbacks from affecting later test or hook invocations (#16343)
  • [jest-circus, jest-jasmine2] Honor --expand when formatting node:assert failures, instead of always collapsing the diff (#16347)
  • [jest-circus, jest-jasmine2, jest-message-util] Serialize the inner errors of an AggregateError into failureMessages, retryReasons and unhandledErrors, so --json output and reporter annotations include them (#16316)
  • [jest-circus, jest-snapshot] Keep snapshot state and counts correct when a test retries (#16344)
  • [@jest/create-cache-key-function] Include the caller support flags in the generated key, so a transformer that emits ESM or CJS based on them no longer shares one cache entry between the two (#16331)
  • [@jest/create-cache-key-function] Include the stringified project config in the generated key, so editing a transformer's own settings invalidates what it cached (#16331)
  • [@jest/transform] Include the caller support flags in a transform's cache key, so a file transformed both as ESM and as CJS no longer serves one shape's output for the other (#16331)
  • [jest-config] Add missing findRelatedTests, outputFile, and replname entries to ValidConfig so they no longer trigger spurious "Unknown option" warnings (#16224)
  • [jest-config] Use --config for the global config when multiple --projects are specified (#16273)
  • [jest-core] Serialize bigint values in --json and --outputFile output as their literal form (4n), instead of failing the run with TypeError: Do not know how to serialize a BigInt (#16338)
  • [jest-core] Do not report a CustomGC async resource (used by N-API addons such as napi-rs for per-isolate GC bookkeeping) as an open handle, since it is napi_unref'd by the addon and can never keep the event loop alive (#16379)
  • [jest-each] Keep a $&, $`, $' or $$ inside a %p param value out of the replacement, so the title shows the value instead of the text around it (#16338)
  • [jest-each] Interpolate a bigint into a %j title as its literal form ("4n") at any depth, instead of throwing TypeError: Do not know how to serialize a BigInt while collecting the tests (#16338)
  • [jest-environment, jest-runtime] Bind sandboxInjectedGlobals to the right values when injectGlobals is false, instead of shifting every one of them by a position (#16377)
  • [jest-environment-node, jest-util] Only warn about a conflicting globalsCleanup mode when one was explicitly configured, and follow the mode that is actually in effect (#16323)
  • [jest-environment-node, jest-util] Stop resolving lazy globals when setting up an environment, so Node 26's builtin module globals are no longer loaded (and no longer emit their deprecation warnings) for every test file (#16324)
  • [jest-haste-map] Keep watch mode alive when an outside process briefly makes a file unreadable on Windows, instead of tearing the watcher down on EPERM (#16295)
  • [jest-haste-map] Keep indexing when an outside process holds a file open on Windows, instead of failing the whole crawl on EPERM (#16358)
  • [jest-haste-map] Keep a duplicated manual mock resolving when the file it pointed at is deleted in watch mode (#16360)
  • [jest-haste-map] Shut the worker farm down when a duplicate manual mock aborts the build under throwOnModuleCollision (#16354)
  • [jest-haste-map] Attach the watchman client's error listener before the first command, so a watchman failure falls back to the node crawler instead of crashing on an unhandled error event, and always end the client (#16355)
  • [jest-haste-map] Stop delivering watch events after WatchmanWatcher is closed, and route its warnings through the configured console (#16355)
  • [jest-haste-map] Restore the nested duplicates index correctly in ModuleMap.fromJSON, so a haste collision reported inside a test worker raises DuplicateHasteCandidatesError instead of a TypeError (#16353)
  • [jest-haste-map] Match watched files on a full extension, so moduleFileExtensions: ['js'] no longer accepts foo.mjs (#16352)
  • [jest-haste-map] Delimit the fields that make up the haste map cache key, so two different option sets cannot hash to the same cache file (#16352)
  • [jest-message-util] Print the inner errors of an AggregateError thrown inside a test (#16316)
  • [jest-message-util] Indent nested cause and AggregateError sections of a test failure by one level per depth, so the nesting is legible instead of rendering flat (#16316)
  • [jest-message-util] Color stack traces line by line so blank lines stay blank (#16316)
  • [jest-message-util] Detect Jest's own frames without assuming the checkout directory's name, and cover @jest/* packages, so stack traces and code frames point at user code (#16326)
  • [jest-mock] mockResolvedValue / mockRejectedValue now see all overload return types, so a Promise-returning overload survives even when a later overload returns a non-Promise (e.g. pg.Client['end']) (#16237)
  • [@jest-environment/jsdom-abstract] Make @types/jsdom a peer dependency (#16166)
  • [jest-mock] Remove the leftover own accessor descriptor when restoring a spyOn of an inherited getter or setter, so the instance keeps reflecting the prototype (#16226)
  • [jest-resolve] Include extensionsToTreatAsEsm in the shouldLoadAsEsm cache key, so projects with different extension lists don't read each other's answers (#16369)
  • [jest-resolve] Make getModuleIDAsync build and cache data: URI module IDs the same way as getModuleID (#16370)
  • [jest-resolve] Keep the node: prefix when resolving a core module asynchronously, so a builtin that only exists prefixed (node:sea, node:sqlite, node:test, node:test/reporters) resolves instead of failing as a missing bare package (#16388)
  • [jest-resolve] Look up manual mocks for node: protocol specifiers under the unprefixed name they are stored as (#16388)
  • [jest-resolve] Apply moduleNameMapper consistently to both spellings of core module specifiers (fs vs node:fs) (#16390)
  • [jest-resolve] Keep virtual and ordinary mock module IDs isolated across test files (#16296)
  • [jest-resolve] Guard missing require.resolve.paths (#16052)
  • [jest-resolve, jest-config, jest-runner] Support a user resolver written as an ES module (#16332)
  • [jest-resolve, jest-runtime] Throw the CJS parse error for ESM syntax in a "type": "commonjs" package or a .cjs file instead of loading it as ESM, matching Node (#16368)
  • [@jest/source-map] Keep source map sources that name a scheme, such as webpack:///, instead of resolving them into a path that does not exist (#16327)
  • [@jest/source-map] Look up --testLocationInResults positions at the right column, and keep a mapping to the first column instead of discarding it (#16327)
  • [@jest/source-map] Warn when a source map cannot be parsed, instead of silently leaving its frames untranslated (#16327)
  • [jest-runner, @jest/source-map] Keep a source-mapped stack for an error thrown after the test environment was torn down (#16327)
  • [jest-runtime, @jest/source-map] Keep source maps past teardown and past the next test file's install, so a stack from a file no earlier stack mentioned still points at the original source (#16330)
  • [jest-runtime] Report that no coverage was collected when getAllV8CoverageInfoCopy is called after teardown, instead of returning an empty result (#16385)
  • [jest-runtime] Cache a CJS module's parsed exports before walking its re-exports, so two modules that re-export each other no longer overflow the stack when imported from ESM (#16363)
  • [jest-runtime] Keep a re-exported ES module's parse failure from marking the re-exporting CommonJS file as ESM, so module.exports = require('./dep.mjs') loads instead of failing with module is not defined (#16363)
  • [jest-runtime] Scope module mocks instantiated inside jest.isolateModules/isolateModulesAsync to that block, so a mock first imported there no longer outlives it - matching how CommonJS mocks already behave (#16365)
  • [jest-runtime] Suspend module isolation while generating an automock, so loading the real module to read its shape no longer populates the isolated registry (#16365)
  • [jest-runtime] Check a cached ES module's status before require() returns it, so a module whose evaluation threw rethrows that error and one left linked by a failed sibling is evaluated instead of returning uninitialized bindings (#16364)
  • [jest-runtime] Report the original ERR_REQUIRE_ASYNC_MODULE when a require() of a top-level-await graph is retried, instead of a spurious "concurrent import()" error (#16364)
  • [jest-runtime] Throw the evaluation error when another caller's import() of the same module failed while we awaited it, instead of resolving with the errored module (#16364)
  • [jest-runtime] Mark the result of require()ing an ES module that has a default export with __esModule: true through a live-binding facade, and serve the same object from require.cache, matching Node (#16367)
  • [jest-runtime] Provide a CommonJS module's exports under the 'module.exports' named export when imported from ESM, matching Node 23+ (#16367)
  • [jest-runtime] Give the test file itself a non-null require.main (#16367)
  • [jest-runtime] Populate module.children with the modules a file loads, matching Node (#16368)
  • [jest-runtime] Provide import.meta.resolve and import.meta.jest in data: URI modules, accept any-case mediatype parameters, and use Node's error codes for invalid data: URIs (#16368)
  • [jest-runtime] Key ES modules by full URL, so query and fragment suffixes create the same module instances as Node and show up in import.meta.url (#16375)
  • [jest-runtime] Share modules between overlapping graphs when a CommonJS module require()s an ES module mid-load, instead of evaluating shared dependencies twice (#16375)
  • [jest-runtime] Throw ERR_REQUIRE_CYCLE_MODULE like Node when a CommonJS module require()s an ES module that is still being loaded, instead of evaluating the module a second time (#16366)
  • [jest-runtime] Key builtin modules in the ESM registry by one canonical specifier (#16341)
  • [jest-runtime] import.meta.resolve() for a builtin uses its node: specifier (#16341)
  • [jest-runtime] Fall back to native ESM when a .js file contains ESM syntax but has no "type":"module" marker (#16152)
  • [jest-runtime] Allow require() of ESM-marked files on Node < 24.9 via transform fallback (#16244)
  • [jest-runtime, @jest/transform] Surface actionable ERR_REQUIRE_ESM error for files with untransformed ESM syntax instead of the generic "unexpected token" message (#16244)
  • [jest-runtime] Support older test environments whose moduleMocker does not implement clearMocksOnScope (#16169)
  • [jest-runtime] Apply jest.unstable_mockModule when the mocked file itself is require()d, not only when it is imported as a dependency (#16389)
  • [jest-runtime] Apply jest.unstable_mockModule to statically imported data: URIs on Node 24.9+, matching dynamic import() (#16389)
  • [jest-runtime] Run an async jest.unstable_mockModule factory once per module instead of twice, and fail the import instead of crashing the worker when the factory rejects (#16389)
  • [jest-runtime] Hide a require(esm) module that failed to evaluate from require.cache, as Node does, instead of exposing a namespace with uninitialized bindings (#16389)
  • [jest-runtime] Strip the byte-order mark when importing a JSON module, matching require() and Node (#16389)
  • [jest-runtime] Throw ERR_REQUIRE_ASYNC_MODULE when require(esm) runs under an async-only custom resolver, instead of silently resolving with the default resolver (#16389)
  • [jest-runtime] Parse imported JSON modules with the test realm's JSON, so their objects pass instanceof Object inside the test like require()d JSON does (#16389)
  • [jest-runtime] Accept every file: URL string in the sandboxed module.createRequire, including one with a localhost authority, as Node does (#16389)
  • [jest-runtime] Point at {virtual: true} when jest.mock or jest.unstable_mockModule is given a module that cannot be resolved (#16389)
  • [jest-reporters] Fix coverage report table formatting in CI/GitHub Actions environments where process.stdout.columns is undefined by falling back to the COLUMNS env var or 80 columns in CI, preserving existing behaviour in other non-TTY environments (#16227)
  • [jest-runtime] Support CJS-in-ESM exports via "module.exports" named exports (#16277)
  • [jest-snapshot] Keep a skipped or failed test's hinted snapshots, instead of reporting them obsolete (#16348)
  • [jest-util] Stop globsToMatcher reusing a cached matcher compiled with different picomatch options, and keep its dot: true default when dot is passed as undefined (#16381)
  • [pretty-format] Move the react-is aliases into the @jest scope, so they cannot be shadowed by unrelated packages published under the alias names (#16333)

Chore & Maintenance

  • [docs] Document the intentional divergences from Node's module system in the ECMAScript Modules page (#16368)
  • [docs] Note deprecation of react-test-renderer in React Native tutorial and pretty-format README (#16294)
  • [docs] Use @testing-library/react-native in the React Native tutorial instead of the deprecated react-test-renderer (#16318)
  • [babel-jest, @jest/transform] Update babel-plugin-istanbul to v8 (#16049)
  • [jest-config, @jest/reporters, jest-runtime] Update glob to v13 (#16397)
  • [jest-haste-map] Refactor massive class into multiple files (#16180)
  • [jest-haste-map] Drop walker dependency; replace hand-rolled directory recursion in the JS crawler and watcher startup with fdir (#16187)
  • [jest-haste-map] Reuse cached metadata for files whose haste name is a known duplicate, instead of re-reading and re-parsing them on every startup (#16351)
  • [jest-haste-map] Cache the watchman socket path and replace the watchman --version probe with get-sockname, so warm runs spawn no watchman processes (#16386)
  • [jest-resolve] Store the per-directory package-type lookup in the cache it reads, so it actually memoizes (#16369)
  • [jest-resolve, jest-runtime] Cut repeated work on the resolution hot path: hoist the platform-extension list to construction, memoize isCoreModule and the options cache-key serialization, skip mapper preparation when no moduleNameMapper is configured, run each mapper regex once, and stop re-parsing NODE_OPTIONS on every default-resolver call (#16371)
  • [jest-resolve] Cut warm resolution cost to about a third: reuse one unrs-resolver factory per options shape instead of cloning per resolution, compose the factory cache key from per-array cached strings instead of serializing options, and stop constructing an Error for misses that findNodeModule swallows; add a __benchmarks__ suite for the default resolver (#16373)
  • [jest-runner, @jest/source-map] Replace source-map-support with an implementation in @jest/source-map (#16327)
  • [jest-snapshot] Load babel, semver and synckit lazily, so requiring the package (which every test process does through @jest/expect) no longer loads ~200 modules that only writing inline snapshots needs (#16387)
  • [jest-runtime] Reduce per-require overhead: skip module ID resolution when no mock can apply, answer core modules before probing for a manual mock, share one require.cache proxy across modules, and cache empty files (#16376)
  • [@jest/source-map] Deprecate getCallsite in favour of SourceMapSupport#getCallsite (#16327)
  • [jest-runtime] Avoid magical null value in ESM loader (#16160)

New Contributors

Full Changelog: v30.4.2...v30.5.0

30.4.0

Big release! 😀

Main feature is a rewrite of our custom runtime in preparation for stabilisation of native support of ESM. As part of that work require(esm) module is now supported on Node 24.9+ (still requires --experimental-vm-modules like before).

In addition we now support fake timers for the recently released Temporal API in Node v26.

React 19 is also supported properly in pretty-format, meaning snapshots of React components now work like they should.

Due to all the changes, there might be regressions that snuck in. Please report them!

Full list of changes below

Features

  • [babel-jest] Support collecting coverage from .mts, .cts (and other) files (#15994)
  • [jest-circus, jest-cli, jest-config, jest-core, jest-jasmine2, jest-types] Add --collect-tests flag to discover and list tests without executing them (#16006)
  • [jest-config, jest-runner, jest-worker] Add workerGracefulExitTimeout config option to control how long workers are given to exit before being force-killed (#15984)
  • [jest-config] Add support for jest.config.mts as a valid configuration file (#16005)
  • [jest-config, jest-core, jest-reporters, jest-runner] verbose and silent can now be set per-project; the project-level value overrides the global value for that project's tests (#16133)
  • [@jest/fake-timers] Accept Temporal.Duration in jest.advanceTimersByTime() and jest.advanceTimersByTimeAsync() (#16128)
  • [@jest/fake-timers] Accept Temporal.Instant and Temporal.ZonedDateTime in jest.setSystemTime() and useFakeTimers({now}) (#16128)
  • [@jest/fake-timers] Support faking Temporal.Now.* (#16131)
  • [jest-mock] Add clearMocksOnScope(scope) on ModuleMocker for clearing every mock function exposed on a scope object (#16088)
  • [jest-resolve] Add canResolveSync() on Resolver so callers can detect when a user-configured resolver only exports an async hook (#16064)
  • [jest-runtime] Use synchronous evaluate() for ES modules without top-level await on Node versions that support it (v24.9+), and prefer the synchronous transform path when a sync transformer is configured (#16062)
  • [jest-runtime] Support require() of ES modules on Node v24.9+ (#16074)
  • [jest-runtime] Validate TC39 import attributes (with { type: 'json' }) on ESM imports (#16127)
  • [@jest/transform] Add canTransformSync(filename) on ScriptTransformer so callers can pick the sync vs async transform path (#16062)
  • [jest-util] Add isError helper (#16076)
  • [pretty-format] Support React 19 (#16123)

Fixes

  • [expect-utils] Fix toStrictEqual failing on structuredClone results due to cross-realm constructor mismatch (#15959)
  • [@jest/expect-utils] Prevent toMatchObject/subset matching from throwing when encountering exotic iterables (#15952)
  • [fake-timers] Convert Date to milliseconds before passing to @sinonjs/fake-timers (#16029)
  • [jest] Export GlobalConfig and ProjectConfig TypeScript types (#16132)
  • [jest-circus] Prevent crash when asyncError is undefined for non-Error throws (#16003)
  • [jest-circus, jest-jasmine2] Include Error.cause in JSON failureMessages output (#15967)
  • [jest-config] Fix preset path resolution on Windows when the preset uses subpath exports (#15961)
  • [jest-config] Allow collectCoverage and coverageProvider in project config without a validation warning (#16132)
  • [jest-config] Project config validator now emits "is not supported in an individual project configuration" instead of "probably a typing mistake" for known global-only options (#16132)
  • [jest-environment-node] Fix --localstorage-file warning on Node 25+ (#16086)
  • [jest-reporters] Apply global coverage threshold to unmatched pattern files in addition to glob/path thresholds (#16137)
  • [jest-reporters, jest-runner, jest-runtime, jest-transform] Fix coverage report not showing correct code coverage when using projects config option (#16140)
  • [jest-runtime] Resolve expect and @jest/expect from the internal module registry so test-file imports share the same JestAssertionError as the global expect (#16130)
  • [jest-runtime] Improve CJS-from-ESM interop: __esModule/Babel default unwrap, broader named-export coverage, and shared CJS singleton across importers (#16050)
  • [jest-runtime] Load .js files with ESM syntax but no "type":"module" marker as native ESM (#16050)
  • [jest-runtime] Extend the .js-with-ESM-syntax fallback to require() on Node v24.9+ - falls back to require(esm) when the CJS parser rejects ESM syntax (#16078)
  • [jest-runtime] Fix deadlocks and double-evaluation in concurrent ESM and wasm imports (#16050)
  • [jest-runtime] Fix error when require() is called after the Jest environment has been torn down (#15951)
  • [jest-runtime] Fix missing error when import() is called after the Jest environment has been torn down (#16080)
  • [jest-runtime] Fix virtual unstable_mockModule registrations not respected in ESM (#16081)
  • [jest-runtime] Apply moduleNameMapper when resolving modules with require.resolve() and the paths option (#16135)

Chore & Maintenance

  • [@jest/fake-timers] Upgrade @sinonjs/fake-timers (#16139)
  • [jest-runtime] Use synchronous linkRequests / instantiate for ESM linking on Node v24.9+ (#16063)

New Contributors

Full Changelog: v30.3.0...v30.4.0

30.2.0

Chore & Maintenance

  • [*] Update example repo for testing React Native projects (#15832)
  • [*] Update jest-watch-typeahead to v3 (#15830)

Features

  • [jest-environment-jsdom-abstract] Add support for JSDOM v27 (#15834)

Fixes

  • [babel-jest] Export the TransformerConfig interface (#15820)
  • [jest-config] Fix jest.config.ts with TS loader specified in docblock pragma (#15839)

30.0.1

What's Changed

Features

  • [jest-resolver] Implement the defaultAsyncResolver (#15679)

Fixes

  • [jest-resolver] Resolve builtin modules correctly (#15683)
  • [jest-environment-node, jest-util] Avoid setting globals cleanup protection symbol when feature is off (#15684)

Chore & Maintenance

  • [*] Remove and deprecate jest-repl package (#15673)
  • [jest-resolver] Replace custom isBuiltinModule with node's isBuiltin (#15685)

New Contributors

Full Changelog: https://github.com/jestjs/jest/blob/main/CHANGELOG.md

30.0.0

Today we are happy to announce the release of Jest 30. This release features a substantial number of changes, fixes, and improvements. While it is one of the largest major releases of Jest ever, we admit that three years for a major release is too long. In the future, we are aiming to make more frequent major releases to keep Jest great for the next decade.

If you want to skip all the news and just get going, run npm install jest@^30.0.0 and follow the migration guide: Upgrading from Jest 29 to 30.

Read the full blog post

Features

  • [*] Renamed globalsCleanupMode to globalsCleanup and --waitNextEventLoopTurnForUnhandledRejectionEvents to --waitForUnhandledRejections
  • [expect] Add ArrayOf asymmetric matcher for validating array elements. (#15567)
  • [babel-jest] Add option excludeJestPreset to allow opting out of babel-preset-jest (#15164)
  • [expect] Revert #15038 to fix expect(fn).toHaveBeenCalledWith(expect.objectContaining(...)) when there are multiple calls (#15508)
  • [jest-circus, jest-cli, jest-config] Add waitNextEventLoopTurnForUnhandledRejectionEvents flag to minimise performance impact of correct detection of unhandled promise rejections introduced in #14315 (#14681)
  • [jest-circus] Add a waitBeforeRetry option to jest.retryTimes (#14738)
  • [jest-circus] Add a retryImmediately option to jest.retryTimes (#14696)
  • [jest-circus, jest-jasmine2] Allow setupFilesAfterEnv to export an async function (#10962)
  • [jest-circus, jest-test-result] Add startedAt timestamp in TestCaseResultObject within onTestCaseResult (#15145)
  • [jest-cli] Export buildArgv (#15310)
  • [jest-config] [BREAKING] Add mts and cts to default moduleFileExtensions config (#14369)
  • [jest-config] [BREAKING] Update testMatch and testRegex default option for supporting mjs, cjs, mts, and cts (#14584)
  • [jest-config] Loads config file from provided path in package.json (#14044)
  • [jest-config] Allow loading jest.config.cts files (#14070)
  • [jest-config] Show rootDir in error message when a preset fails to load (#15194)
  • [jest-config] Support loading TS config files using esbuild-register via docblock loader (#15190)
  • [jest-config] Allow passing TS config loader options via docblock comment (#15234)
  • [jest-config] If Node is running with type stripping enabled, do not require a TS loader (#15480)
  • [@jest/core] Group together open handles with the same stack trace (#13417, & #14789)
  • [@jest/core] Add perfStats to surface test setup overhead (#14622)
  • [@jest/core] [BREAKING] Changed --filter to accept an object with shape { filtered: Array<string> } to match documentation (#13319)
  • [@jest/core] Support --outputFile option for --listTests (#14980)
  • [@jest/core] Stringify Errors properly with --json flag (#15329)
  • [@jest/core, @jest/test-sequencer] [BREAKING] Exposes globalConfig & contexts to TestSequencer (#14535, & #14543)
  • [jest-each] Introduce %$ option to add number of the test to its title (#14710)
  • [@jest/environment] [BREAKING] Remove deprecated jest.genMockFromModule() (#15042)
  • [@jest/environment] [BREAKING] Remove unnecessary defensive code (#15045)
  • [jest-environment-jsdom] [BREAKING] Upgrade JSDOM to v22 (#13825)
  • [@jest/environment-jsdom-abstract] Introduce new package which abstracts over the jsdom environment, allowing usage of custom versions of JSDOM (#14717)
  • [jest-environment-node] Update jest environment with dispose symbols Symbol (#14888 & #14909)
  • [expect, @jest/expect] [BREAKING] Add type inference for function parameters in CalledWith assertions (#15129)
  • [@jest/expect-utils] Properly compare all types of TypedArrays (#15178)
  • [@jest/fake-timers] [BREAKING] Upgrade @sinonjs/fake-timers to v13 (#14544 & #15470)
  • [@jest/fake-timers] Exposing new modern timers function advanceTimersToFrame() which advances all timers by the needed milliseconds to execute callbacks currently scheduled with requestAnimationFrame (#14598)
  • [jest-matcher-utils] Add SERIALIZABLE_PROPERTIES to allow custom serialization of objects (#14893)
  • [jest-mock] Add support for the Explicit Resource Management proposal to use the using keyword with jest.spyOn(object, methodName) (#14895)
  • [jest-reporters] Add support for DEC mode 2026 (#15008)
  • [jest-resolver] Support file:// URLs as paths (#15154)
  • [jest-resolve,jest-runtime,jest-resolve-dependencies] Pass the conditions when resolving stub modules (#15489)
  • [jest-runtime] Exposing new modern timers function jest.advanceTimersToFrame() from @jest/fake-timers (#14598)
  • [jest-runtime] Support import.meta.filename and import.meta.dirname (available from Node 20.11) (#14854)
  • [jest-runtime] Support import.meta.resolve (#14930)
  • [jest-runtime] [BREAKING] Make it mandatory to pass globalConfig to the Runtime constructor (#15044)
  • [jest-runtime] Add unstable_unmockModule (#15080)
  • [jest-runtime] Add onGenerateMock transformer callback for auto generated callbacks (#15433 & #15482)
  • [jest-runtime] [BREAKING] Use vm.compileFunction over vm.Script (#15461)
  • [@jest/schemas] Upgrade @sinclair/typebox to v0.34 (#15450)
  • [@jest/types] test.each(): Accept a readonly (as const) table properly (#14565)
  • [@jest/types] Improve argument type inference passed to test and describe callback functions from each tables (#14920)
  • [jest-snapshot] [BREAKING] Add support for Error causes in snapshots (#13965)
  • [jest-snapshot] Support Prettier 3 (#14566)
  • [@jest/util-snapshot] Extract utils used by tooling from jest-snapshot into its own package (#15095)
  • [pretty-format] [BREAKING] Do not render empty string children ('') in React plugin (#14470)

Fixes

  • [expect] Show AggregateError to display (#15346)
  • [*] Replace exit with exit-x (#15399)
  • [babel-plugin-jest-hoist] Use denylist instead of the deprecated blacklist for Babel 8 support (#14109)
  • [babel-plugin-jest-hoist] Do not rely on buggy Babel behaviour (#15415)
  • [expect] Check error instance type for toThrow/toThrowError (#14576)
  • [expect] Improve diff for failing expect.objectContaining (#15038)
  • [expect] Use Array.isArray to check if an array is an Array (#15101)
  • [expect] Fix Error cause assertion errors (#15339)
  • [jest-changed-files] Print underlying errors when VCS commands fail (#15052)
  • [jest-changed-files] Abort sl root call if output resembles a steam locomotive (#15053)
  • [jest-circus] [BREAKING] Prevent false test failures caused by promise rejections handled asynchronously (#14315)
  • [jest-circus] Replace recursive makeTestResults implementation with iterative one (#14760)
  • [jest-circus] Omit expect.hasAssertions() errors if a test already has errors (#14866)
  • [jest-circus, jest-expect, jest-snapshot] Pass test.failing tests when containing failing snapshot matchers (#14313)
  • [jest-circus] Concurrent tests now emit jest circus events at the correct point and in the expected order. (#15381)
  • [jest-cli] [BREAKING] Validate CLI flags that require arguments receives them (#14783)
  • [jest-config] Make sure to respect runInBand option (#14578)
  • [jest-config] Support testTimeout in project config (#14697)
  • [jest-config] Support coverageReporters in project config (#14697)
  • [jest-config] Allow reporters in project config (#14768)
  • [jest-config] Allow Node16/NodeNext/Bundler moduleResolution in project's tsconfig (#14739)
  • [@jest/create-cache-key-function] Correct the return type of createCacheKey (#15159)
  • [jest-each] Allow $keypath templates with null or undefined values (#14831)
  • [@jest/expect-utils] Fix comparison of DataView (#14408)
  • [@jest/expect-utils] [BREAKING] exclude non-enumerable in object matching (#14670)
  • [@jest/expect-utils] Fix comparison of URL (#14672)
  • [@jest/expect-utils] Check Symbol properties in equality (#14688)
  • [@jest/expect-utils] Catch circular references within arrays when matching objects (#14894)
  • [@jest/expect-utils] Fix not addressing to Sets and Maps as objects without keys (#14873)
  • [jest-haste-map] Fix errors or clobbering with multiple hasteImplModulePaths (#15522)
  • [jest-leak-detector] Make leak-detector more aggressive when running GC (#14526)
  • [jest-runtime] Properly handle re-exported native modules in ESM via CJS (#14589)
  • [jest-runtime] Refactor _importCoreModel so required core module is consistent if modified while loading (#15077)
  • [jest-schemas, jest-types] [BREAKING] Fix type of testFailureExitCode config option(#15232)
  • [jest-util] Make sure isInteractive works in a browser (#14552)
  • [pretty-format] [BREAKING] Print ArrayBuffer and DataView correctly (#14290)
  • [pretty-format] Fixed a bug where "anonymous custom elements" were not being printed as expected. (#15138)
  • [jest-cli] When specifying paths on the command line, only match against the relative paths of the test files (#12519)
    • [BREAKING] Changes testPathPattern configuration option to testPathPatterns, which now takes a list of patterns instead of the regex.
    • [BREAKING] --testPathPattern is now --testPathPatterns
    • [BREAKING] Specifying testPathPatterns when programmatically calling watch must be specified as new TestPathPatterns(patterns), where TestPathPatterns can be imported from @jest/pattern
  • [jest-reporters, jest-runner] Unhandled errors without stack get correctly logged to console (#14619)
  • [jest-util] Always load mjs files with import (#15447)
  • [jest-worker] Properly handle a circular reference error when worker tries to send an assertion fails where either the expected or actual value is circular (#15191)
  • [jest-worker] Properly handle a BigInt when worker tries to send an assertion fails where either the expected or actual value is BigInt (#15191)
  • [expect] Resolve issue where ObjectContaining matched non-object values. ([#15463])(#15463).
    • Adds a conditional/check to ensure the argument passed to expect is an object.
    • Add unit tests for new ObjectContaining behavior.
    • Remove invalid/wrong test case assertions for ObjectContaining.
  • [jest-worker] Addresses incorrect state on exit (#15610)

Performance

  • [*] [BREAKING] Bundle all of Jest's modules into index.js (#12348, #14550 & #14661)
  • [jest-haste-map] Only spawn one process to check for watchman installation (#14826)
  • [jest-runner] Better cleanup source-map-support after test to resolve (minor) memory leak (#15233)
  • [jest-circus, jest-environment-node, jest-repl, jest-runner, jest-util] Cleanup global variables on environment teardown to reduce memory leaks (#15215 & #15636 & #15643)

Chore & Maintenance

  • [jest-environment-jsdom, jest-environment-jsdom-abstract] Increased version of jsdom to ^26.0.0 (#15325CVE-2024-37890)
  • [*] Increase version of micromatch to ^4.0.7 (#15082)
  • [*] [BREAKING] Drop support for Node.js versions 14, 16, 19, 21 and 23 (#14460, #15118, #15623, #15640)
  • [*] [BREAKING] Drop support for typescript@4.3, minimum version is now 5.4 (#14542, #15621)
  • [*] Depend on exact versions of monorepo dependencies instead of ^ range (#14553)
  • [*] [BREAKING] Add ESM wrapper for all of Jest's modules (#14661)
  • [*] [BREAKING] Upgrade to glob@10 (#14509)
  • [*] Use TypeError over Error where appropriate (#14799)
  • [docs] Fix typos in CHANGELOG.md and packages/jest-validate/README.md (#14640)
  • [docs] Don't use alias matchers in docs (#14631)
  • [babel-jest, babel-preset-jest] [BREAKING] Increase peer dependency of @babel/core to ^7.11 (#14109)
  • [babel-jest, @jest/transform] Update babel-plugin-istanbul to v6 (#15156)
  • [babel-plugin-jest-hoist] Move unnecessary dependencies to devDependencies (#15010)
  • [expect] [BREAKING] Remove .toBeCalled(), .toBeCalledTimes(), .toBeCalledWith(), .lastCalledWith(), .nthCalledWith(), .toReturn(), .toReturnTimes(), .toReturnWith(), .lastReturnedWith(), .nthReturnedWith() and .toThrowError() matcher aliases (#14632)
  • [jest-cli, jest-config, @jest/types] [BREAKING] Remove deprecated --init argument (#14490)
  • [jest-config, @jest/core, jest-util] Upgrade ci-info (#14655)
  • [jest-mock] [BREAKING] Remove MockFunctionMetadataType, MockFunctionMetadata and SpyInstance types (#14621)
  • [@jest/reporters] Upgrade istanbul-lib-source-maps (#14924)
  • [jest-schemas] Upgrade @sinclair/typebox (#14775)
  • [jest-transform] Upgrade write-file-atomic (#14274)
  • [jest-util] Upgrade picomatch to v4 (#14653 & #14885)
  • [docs] Append to NODE_OPTIONS, not overwrite ([#14730](https://github.com/jestjs/jest/pull/14730))
  • [docs] Updated .toHaveBeenCalled() documentation to correctly reflect its functionality (#14842)
  • [docs] Link NestJS documentation on testing with Jest (#14940)
  • [docs] Revised documentation for .toHaveBeenCalled() to accurately depict its functionality. (#14853)
  • [docs] Removed ExpressJS reference link from documentation due to dead link (#15270)
  • [docs] Correct broken links in docs (#15359)

See the CHANGELOG.

29.7.0

Features

  • [create-jest] Add npm init / yarn create initialiser for Jest projects (#14465)
  • [jest-validate] Allow deprecation warnings for unknown options (#14499)

Fixes

  • [jest-resolver] Replace unmatched capture groups in moduleNameMapper with empty string instead of undefined (#14507)
  • [jest-snapshot] Allow for strings as well as template literals in inline snapshots (#14465)
  • [@jest/test-sequencer] Calculate test runtime if perStats.duration is missing (#14473)

Performance

  • [@jest/create-cache-key-function] Cache access of NODE_ENV and BABEL_ENV (#14455)

Chore & Maintenance

  • [jest-cli] Move internal config initialisation logic to the create-jest package (#14465)

New Contributors

Full Changelog: v29.6.4...v29.7.0

29.6.3

Fixes

  • [expect, @jest/expect-utils] ObjectContaining support symbol as key (#14414)
  • [expect] Remove @types/node from dependencies (#14385)
  • [jest-core] Use workers in watch mode by default to avoid crashes (#14059 & #14085).
  • [jest-reporters] Update istanbul-lib-instrument dependency to v6. (#14401)
  • [jest-mock] Revert #13692 as it was a breaking change (#14429)
  • [jest-mock] Revert #13866 as it was a breaking change (#14429)
  • [jest-mock] Revert #13867 as it was a breaking change (#14429)
  • [@jest/reporters] Marks Reporter's hooks as optional (#14433)
  • [jest-runtime] Fix dynamic ESM import module bug when loaded module through jest.isolateModulesAsync (#14397)

Chore & Maintenance

  • [jest-changed-files, jest-circus, jest-console, @jest/core, @jest/runtime, @jest/transform] Use invariant and notEmpty from jest-util rather than own internal (#14366)

New Contributors

Full Changelog: v29.6.2...v29.6.3

29.4.3

Features

  • [expect] Update toThrow() to be able to use error causes (#13606)
  • [jest-core] allow to use workerIdleMemoryLimit with only 1 worker or runInBand option (#13846)
  • [jest-message-util] Add support for error causes (#13868 & #13912)
  • [jest-runtime] Revert import assertions for JSON modules as it's been relegated to Stage 2 (#13911)

Fixes

  • [@jest/expect-utils] subsetEquality should consider also an object's inherited string keys (#13824)
  • [jest-mock] Clear mock state when jest.restoreAllMocks() is called (#13867)
  • [jest-mock] Prevent mockImplementationOnce and mockReturnValueOnce bleeding into withImplementation (#13888)
  • [jest-mock] Do not restore mocks when jest.resetAllMocks() is called (#13866)

New Contributors

Full Changelog: v29.4.2...v29.4.3

29.4.2

Features

Fixes

  • [expect, @jest/expect] Provide type of actual as a generic argument to Matchers to allow better-typed extensions (#13848)
  • [jest-circus] Added explicit mention of test failing because done() is not being called in error message (#13847)
  • [jest-runtime] Handle CJS re-exports of node core modules from ESM (#13856)
  • [jest-transform] Downgrade write-file-atomic to v4 (#13853)
  • [jest-worker] Ignore IPC messages not intended for Jest (#13543)

Chore & Maintenance

  • [*] make sure to exclude .eslintcache from published module (#13832)
  • [docs] Cleanup incorrect links in CHANGELOG.md (#13857)

New Contributors

Full Changelog: v29.4.1...v29.4.2

29.2.0

Features

  • [@jest/cli, jest-config] A seed for the test run will be randomly generated, or set by a CLI option (#13400)
  • [@jest/cli, jest-config] --show-seed will display the seed value in the report, and can be set via a CLI flag or through the config file (#13400)
  • [jest-config] Add readInitialConfig utility function (#13356)
  • [jest-core] Allow testResultsProcessor to be async (#13343)
  • [@jest/environment, jest-environment-node, jest-environment-jsdom, jest-runtime] Add getSeed() to the jest object (#13400)
  • [expect, @jest/expect-utils] Allow isA utility to take a type argument (#13355)
  • [expect] Expose AsyncExpectationResult and SyncExpectationResult types (#13411)

Fixes

  • [babel-plugin-jest-hoist] Ignore TSTypeQuery when checking for hoisted references (#13367)
  • [jest-core] Fix detectOpenHandles false positives for some special objects such as TLSWRAP (#13414)
  • [jest-mock] Fix mocking of getters and setters on classes (#13398)
  • [jest-reporters] Revert: Transform file paths into hyperlinks (#13399)
  • [@jest/types] Infer type of each table correctly when the table is a tuple or array (#13381)
  • [@jest/types] Rework typings to allow the *ReturnedWith matchers to be called with no argument (#13385)

Chore & Maintenance

  • [*] Update @babel/* deps, resulting in slightly different stack traces for each (#13422)

Performance

  • [jest-runner] Do not instrument v8 coverage data if coverage should not be collected (#13282)

New Contributors

Full Changelog: v29.1.2...v29.2.0

29.0.0

Blog post: https://jestjs.io/blog/2022/08/25/jest-29

Features

  • [expect] [BREAKING] Differentiate between MatcherContext MatcherUtils and MatcherState types (#13141)
  • [jest-circus] Add support for test.failing.each (#13142)
  • [jest-config] [BREAKING] Make snapshotFormat default to escapeString: false and printBasicPrototype: false (#13036)
  • [jest-config] [BREAKING] Remove undocumented collectCoverageOnlyFrom option (#13156)
  • [jest-environment-jsdom] [BREAKING] Upgrade to jsdom@20 (#13037, #13058)
  • [@jest/globals] Add jest.Mocked, jest.MockedClass, jest.MockedFunction and jest.MockedObject utility types (#12727)
  • [jest-mock] [BREAKING] Refactor Mocked* utility types. MaybeMockedDeep and MaybeMocked became Mocked and MockedShallow respectively; only deep mocked variants of MockedClass, MockedFunction and MockedObject are exported (#13123, #13124)
  • [jest-mock] [BREAKING] Change the default jest.mocked helper’s behavior to deep mocked (#13125)
  • [jest-snapshot] [BREAKING] Let babel find config when updating inline snapshots (#13150)
  • [@jest/test-result, @jest/types] [BREAKING] Replace Bytes and Milliseconds types with number (#13155)
  • [jest-worker] Adds workerIdleMemoryLimit option which is used as a check for worker memory leaks >= Node 16.11.0 and recycles child workers as required (#13056, #13105, #13106, #13107)
  • [pretty-format] [BREAKING] Remove ConvertAnsi plugin in favour of jest-serializer-ansi-escapes (#13040)
  • [pretty-format] Allow to opt out from sorting object keys with compareKeys: null (#12443)

Fixes

  • [jest-config] Fix testing multiple projects with TypeScript config files (#13099)
  • [@jest/expect-utils] Fix deep equality of ImmutableJS Record (#13055)
  • [jest-haste-map] Increase the maximum possible file size that jest-haste-map can handle (#13094)
  • [jest-runtime] Properly support CJS re-exports from dual packages (#13170)
  • [jest-snapshot] Make prettierPath optional in SnapshotState (#13149)
  • [jest-snapshot] Fix parsing error from inline snapshot files with JSX (#12760)
  • [jest-worker] When a process runs out of memory worker exits correctly and doesn't spin indefinitely (#13054)

Chore & Maintenance

  • [*] [BREAKING] Drop support for Node v12 and v17 (#13033)
  • [docs] Fix webpack name (#13049)
  • [docs] Explicit how to set n for --bail (#13128)
  • [docs] Update Enzyme URL (#13166)
  • [jest-leak-detector] Remove support for weak-napi (#13035)
  • [jest-snapshot] [BREAKING] Require rootDir as argument to SnapshotState (#13150)

New Contributors

Full Changelog: v28.1.3...v29.0.0

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ jest-each (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ jest-environment-node (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ jest-haste-map (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ jest-leak-detector (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

30.5.0

On a personal note: King Harald V of Norway passed away this morning. He ascended the throne 35 years ago, two months before I was born. This release is dedicated to his memory. Hvil i fred 🇳🇴


This is a big release. It touches jest-runtime, jest-resolve and jest-haste-map in many places, and with this many changes there might be regressions 😬. If your suite behaves differently after upgrading, please open an issue.

Highlights

whenCalledWith

Mock functions can now configure return values per argument list, contributed by @timkindberg (#16053):

const fn = jest.fn();
fn.whenCalledWith('apple').mockReturnValue('red');
fn.whenCalledWith('banana').mockReturnValue('yellow');
fn.whenCalledWith(expect.any(Number)).mockReturnValue('numeric');

fn('apple'); // 'red'
fn('banana'); // 'yellow'
fn(42); // 'numeric'
fn('grape'); // undefined

The returned object is a real Mock, so mockReturnValueOnce, mockResolvedValue, mockImplementation etc. all chain here too. Argument slots accept literals or any asymmetric matcher, with the same equality semantics as toHaveBeenCalledWith(). Calls that match nothing fall through to the base mock. See the Mock Functions docs for matching and precedence details.

Describe-level retries

jest.retryTimes() can now retry a whole describe block instead of a single test, contributed by @soltonigiri (#16322). Each attempt reruns the block's beforeAll/afterAll hooks, child tests and nested describes, which helps when tests in a block depend on shared state:

describe('workflow', () => {
  jest.retryTimes(3, {entireDescribe: true});

  test('first step', () => {});
  test('second step', () => {}); // a failure retries the entire block
});

New file watcher

The non-watchman path of jest-haste-map is rewritten. @parcel/watcher replaces the homegrown NodeWatcher and FSEventsWatcher (#16188), and fdir replaces the hand-rolled directory recursion in the crawler (#16187). A batch of fixes also makes watching and indexing survive locked files on Windows, watchman failures, and duplicate manual mocks (#16295, #16358, #16355, #16360).

If you can, please run your suite with --no-watchman (in and out of watch mode) to exercise the new crawler and watchers, and report anything odd 👍

Long-requested dependency updates

  • babel-plugin-istanbul is updated to v8 (#16049)
  • glob is updated to v13 (#16397)
  • source-map-support is replaced with an implementation in @jest/source-map (#16327). This fixes a memory leak where source-map-support's process-global caches pinned every finished test file's sandbox. Source maps also survive environment teardown, --testLocationInResults looks up the right column, and scheme-prefixed sources like webpack:/// are kept as-is.

Performance

  • Warm module resolution costs about a third of what it did, and repeated work is gone from the resolution hot path (#16373, #16371).
  • Per-require overhead in jest-runtime is cut: module ID resolution is skipped when no mock can apply, and core modules answer before the manual-mock probe (#16376).
  • jest-snapshot loads babel, semver and synckit lazily, so every test process loads ~200 fewer modules (#16387).
  • jest-haste-map caches the watchman socket path, so warm runs spawn no watchman processes (#16386), and reuses cached metadata for duplicated haste names instead of re-parsing them on every startup (#16351).

More new APIs

  • Snapshot failures expose the .snap file path as matcherResult.snapshotPath in failureDetails (#16374).
  • --collectTests expands test.each/describe.each cases and reports per-status counts plus a summary line that matches a real run (#16259).
  • AggregateError inner errors and nested cause chains render with code frames and per-level indentation, and are included in --json output, retryReasons and reporter annotations (#16316).

ESM

A long list of fixes brings jest-runtime's module system closer to Node's:

  • Automocking and manual __mocks__ files now apply to ESM on Node 24.9+. Static imports, dynamic import() and require() of an ESM file generate an automock from the real module's namespace instead of failing with "Attempting to import a mock without a factory" (#16391).
  • Many jest.unstable_mockModule gaps are closed: mocks apply when the mocked file is require()d directly, async factories run once and fail the import instead of crashing the worker 😅, and mocks made inside jest.isolateModules stay scoped to that block (#16389, #16365).
  • require(esm), CJS/ESM interop, import.meta, data: URIs and error ordering now match Node in dozens of edge cases. See the Fixes section for the full list (#16364 through #16391).
  • The module-sync export condition resolves, so packages that expose their ESM entry point for require() load the same file Node picks (#16336).

The intentional divergences from Node's module system are now documented on the ECMAScript Modules page (#16368).

Resolver

  • The default resolver honors Node's --preserve-symlinks / NODE_PRESERVE_SYMLINKS (#16260).
  • moduleNameMapper applies to both spellings of core module specifiers (fs and node:fs), and builtins that only exist prefixed (node:sqlite, node:test) resolve asynchronously (#16390, #16388).
  • A user resolver can be written as an ES module (#16332).

On top of the highlights there are ~60 fixes across jest-circus, jest-haste-map, jest-config, jest-mock and the transform cache keys. See the full changelog below 😀


Features

  • [@jest/expect-utils, jest-mock] Add mockFn.whenCalledWith(...args) for configuring return values per argument list, with first-class asymmetric-matcher support (#16053)
  • [@jest/expect-utils] Export AsymmetricMatcher and FunctionParameters types (previously private to expect) (#16053)
  • [jest-circus, jest-core, jest-jasmine2, jest-test-result, jest-types] --collectTests now expands test.each/describe.each cases and reports per-status counts (skipped/todo via the new wouldRun flag for selected tests) plus a summary line that match a real run, including under --testNamePattern and .only/fdescribe focus on both the circus and jasmine2 runners (#16259)
  • [jest-circus, jest-environment, jest-runtime, jest-types] Add describe-level retries via jest.retryTimes(..., {entireDescribe: true}) (#16322)
  • [jest-circus, jest-message-util, jest-reporters, jest-types] Add retryMessages to AssertionResult and export formatErrorStack, so the retry log renders nested cause and AggregateError sections with code frames instead of serialized [cause]:/[errors]: markers (#16316)
  • [jest-circus, jest-types] Add unhandledErrorsDetailed to Circus.RunResult, so an unhandled rejection reports its cause chain and AggregateError entries with code frames instead of a pre-serialized stack (#16316)
  • [jest-haste-map] Replace NodeWatcher and FSEventsWatcher with @parcel/watcher for the non-watchman watch path (#16188)
  • [jest-resolve] Bump unrs-resolver to 1.12.1, remove jest-pnp-resolver and unnecessary checks (#15721)
  • [jest-resolve] Honor Node's --preserve-symlinks / NODE_PRESERVE_SYMLINKS in the default resolver by passing symlinks: false to unrs-resolver (#16260)
  • [jest-runtime] Apply automocking and manual __mocks__ files to synchronously evaluable ESM graphs on Node 24.9+ - static imports, dynamic import() and require() of an ESM file now generate an automock from the real module's namespace instead of failing with "Attempting to import a mock without a factory". Graphs that need async evaluation (top-level await) or an async-only resolver or transformer still throw (#16391)
  • [jest-runtime] Route process.getBuiltinModule through the sandbox, so it returns the sandbox process and the hooked node:module instead of the host's (#16391)
  • [jest-runtime] Throw an actionable error from module.register() and module.registerHooks() inside a test - the hooks attached to the loader running Jest itself, never saw the sandboxed requires they were meant for, and stayed registered for every later test file in the worker (#16391)
  • [jest-runtime] Surface resolution and import-attribute errors in an ESM graph before executing any of its CJS dependencies on Node 24.9+, matching Node's run-nothing-on-a-broken-graph behavior; the legacy loader on older versions keeps its linking-time execution order (#16391)
  • [jest-runtime] Throw ERR_SOURCE_PHASE_NOT_DEFINED with an actionable message for import source and import.source(), instead of failing at instantiation with V8's bare "Source phase import object is not defined" (#16391)
  • [jest-runtime] Emit the JSON-without-import-attribute deprecation warning once per test file instead of once per worker, so it is no longer silently swallowed for every file after the first (#16391)
  • [jest-runtime] Set import.meta.main to true in the test file and false in every module it loads, matching Node 24+ (#16367)
  • [jest-runtime] Resolve the module-sync export condition, so a package that exposes its ESM entry point for require() loads the same file Node would (#16336)
  • [jest-snapshot] Add external snapshot paths to custom reporter failure details (#16374)

Fixes

  • [jest-console, jest-reporters] CustomConsole now buffers console output so TestResult.console is populated for reporters when verbose is enabled, while GitHubActionsReporter avoids replaying buffered output in verbose mode (#16155)
  • [expect, jest-message-util, jest-pattern, jest-regex-util, jest-util] Revert node: protocol imports to restore webpack/browser-bundle compatibility (#16167)
  • [expect] Widen toMatchObject and objectContaining parameter type from Record<string, unknown> to object so class instances are accepted (#16196)
  • [jest-circus] Call a generator test body with the shared test context, so this matches what a regular test function receives (#16347)
  • [jest-circus] Capture the error listeners of the parent process instead of the in-sandbox process, so listeners registered before the test file survive teardown and sandbox listeners no longer leak onto the parent (#16347)
  • [jest-circus] Clear currentlyRunningTest after skipped and todo tests (#16342)
  • [jest-circus] Prevent late done() callbacks from affecting later test or hook invocations (#16343)
  • [jest-circus, jest-jasmine2] Honor --expand when formatting node:assert failures, instead of always collapsing the diff (#16347)
  • [jest-circus, jest-jasmine2, jest-message-util] Serialize the inner errors of an AggregateError into failureMessages, retryReasons and unhandledErrors, so --json output and reporter annotations include them (#16316)
  • [jest-circus, jest-snapshot] Keep snapshot state and counts correct when a test retries (#16344)
  • [@jest/create-cache-key-function] Include the caller support flags in the generated key, so a transformer that emits ESM or CJS based on them no longer shares one cache entry between the two (#16331)
  • [@jest/create-cache-key-function] Include the stringified project config in the generated key, so editing a transformer's own settings invalidates what it cached (#16331)
  • [@jest/transform] Include the caller support flags in a transform's cache key, so a file transformed both as ESM and as CJS no longer serves one shape's output for the other (#16331)
  • [jest-config] Add missing findRelatedTests, outputFile, and replname entries to ValidConfig so they no longer trigger spurious "Unknown option" warnings (#16224)
  • [jest-config] Use --config for the global config when multiple --projects are specified (#16273)
  • [jest-core] Serialize bigint values in --json and --outputFile output as their literal form (4n), instead of failing the run with TypeError: Do not know how to serialize a BigInt (#16338)
  • [jest-core] Do not report a CustomGC async resource (used by N-API addons such as napi-rs for per-isolate GC bookkeeping) as an open handle, since it is napi_unref'd by the addon and can never keep the event loop alive (#16379)
  • [jest-each] Keep a $&, $`, $' or $$ inside a %p param value out of the replacement, so the title shows the value instead of the text around it (#16338)
  • [jest-each] Interpolate a bigint into a %j title as its literal form ("4n") at any depth, instead of throwing TypeError: Do not know how to serialize a BigInt while collecting the tests (#16338)
  • [jest-environment, jest-runtime] Bind sandboxInjectedGlobals to the right values when injectGlobals is false, instead of shifting every one of them by a position (#16377)
  • [jest-environment-node, jest-util] Only warn about a conflicting globalsCleanup mode when one was explicitly configured, and follow the mode that is actually in effect (#16323)
  • [jest-environment-node, jest-util] Stop resolving lazy globals when setting up an environment, so Node 26's builtin module globals are no longer loaded (and no longer emit their deprecation warnings) for every test file (#16324)
  • [jest-haste-map] Keep watch mode alive when an outside process briefly makes a file unreadable on Windows, instead of tearing the watcher down on EPERM (#16295)
  • [jest-haste-map] Keep indexing when an outside process holds a file open on Windows, instead of failing the whole crawl on EPERM (#16358)
  • [jest-haste-map] Keep a duplicated manual mock resolving when the file it pointed at is deleted in watch mode (#16360)
  • [jest-haste-map] Shut the worker farm down when a duplicate manual mock aborts the build under throwOnModuleCollision (#16354)
  • [jest-haste-map] Attach the watchman client's error listener before the first command, so a watchman failure falls back to the node crawler instead of crashing on an unhandled error event, and always end the client (#16355)
  • [jest-haste-map] Stop delivering watch events after WatchmanWatcher is closed, and route its warnings through the configured console (#16355)
  • [jest-haste-map] Restore the nested duplicates index correctly in ModuleMap.fromJSON, so a haste collision reported inside a test worker raises DuplicateHasteCandidatesError instead of a TypeError (#16353)
  • [jest-haste-map] Match watched files on a full extension, so moduleFileExtensions: ['js'] no longer accepts foo.mjs (#16352)
  • [jest-haste-map] Delimit the fields that make up the haste map cache key, so two different option sets cannot hash to the same cache file (#16352)
  • [jest-message-util] Print the inner errors of an AggregateError thrown inside a test (#16316)
  • [jest-message-util] Indent nested cause and AggregateError sections of a test failure by one level per depth, so the nesting is legible instead of rendering flat (#16316)
  • [jest-message-util] Color stack traces line by line so blank lines stay blank (#16316)
  • [jest-message-util] Detect Jest's own frames without assuming the checkout directory's name, and cover @jest/* packages, so stack traces and code frames point at user code (#16326)
  • [jest-mock] mockResolvedValue / mockRejectedValue now see all overload return types, so a Promise-returning overload survives even when a later overload returns a non-Promise (e.g. pg.Client['end']) (#16237)
  • [@jest-environment/jsdom-abstract] Make @types/jsdom a peer dependency (#16166)
  • [jest-mock] Remove the leftover own accessor descriptor when restoring a spyOn of an inherited getter or setter, so the instance keeps reflecting the prototype (#16226)
  • [jest-resolve] Include extensionsToTreatAsEsm in the shouldLoadAsEsm cache key, so projects with different extension lists don't read each other's answers (#16369)
  • [jest-resolve] Make getModuleIDAsync build and cache data: URI module IDs the same way as getModuleID (#16370)
  • [jest-resolve] Keep the node: prefix when resolving a core module asynchronously, so a builtin that only exists prefixed (node:sea, node:sqlite, node:test, node:test/reporters) resolves instead of failing as a missing bare package (#16388)
  • [jest-resolve] Look up manual mocks for node: protocol specifiers under the unprefixed name they are stored as (#16388)
  • [jest-resolve] Apply moduleNameMapper consistently to both spellings of core module specifiers (fs vs node:fs) (#16390)
  • [jest-resolve] Keep virtual and ordinary mock module IDs isolated across test files (#16296)
  • [jest-resolve] Guard missing require.resolve.paths (#16052)
  • [jest-resolve, jest-config, jest-runner] Support a user resolver written as an ES module (#16332)
  • [jest-resolve, jest-runtime] Throw the CJS parse error for ESM syntax in a "type": "commonjs" package or a .cjs file instead of loading it as ESM, matching Node (#16368)
  • [@jest/source-map] Keep source map sources that name a scheme, such as webpack:///, instead of resolving them into a path that does not exist (#16327)
  • [@jest/source-map] Look up --testLocationInResults positions at the right column, and keep a mapping to the first column instead of discarding it (#16327)
  • [@jest/source-map] Warn when a source map cannot be parsed, instead of silently leaving its frames untranslated (#16327)
  • [jest-runner, @jest/source-map] Keep a source-mapped stack for an error thrown after the test environment was torn down (#16327)
  • [jest-runtime, @jest/source-map] Keep source maps past teardown and past the next test file's install, so a stack from a file no earlier stack mentioned still points at the original source (#16330)
  • [jest-runtime] Report that no coverage was collected when getAllV8CoverageInfoCopy is called after teardown, instead of returning an empty result (#16385)
  • [jest-runtime] Cache a CJS module's parsed exports before walking its re-exports, so two modules that re-export each other no longer overflow the stack when imported from ESM (#16363)
  • [jest-runtime] Keep a re-exported ES module's parse failure from marking the re-exporting CommonJS file as ESM, so module.exports = require('./dep.mjs') loads instead of failing with module is not defined (#16363)
  • [jest-runtime] Scope module mocks instantiated inside jest.isolateModules/isolateModulesAsync to that block, so a mock first imported there no longer outlives it - matching how CommonJS mocks already behave (#16365)
  • [jest-runtime] Suspend module isolation while generating an automock, so loading the real module to read its shape no longer populates the isolated registry (#16365)
  • [jest-runtime] Check a cached ES module's status before require() returns it, so a module whose evaluation threw rethrows that error and one left linked by a failed sibling is evaluated instead of returning uninitialized bindings (#16364)
  • [jest-runtime] Report the original ERR_REQUIRE_ASYNC_MODULE when a require() of a top-level-await graph is retried, instead of a spurious "concurrent import()" error (#16364)
  • [jest-runtime] Throw the evaluation error when another caller's import() of the same module failed while we awaited it, instead of resolving with the errored module (#16364)
  • [jest-runtime] Mark the result of require()ing an ES module that has a default export with __esModule: true through a live-binding facade, and serve the same object from require.cache, matching Node (#16367)
  • [jest-runtime] Provide a CommonJS module's exports under the 'module.exports' named export when imported from ESM, matching Node 23+ (#16367)
  • [jest-runtime] Give the test file itself a non-null require.main (#16367)
  • [jest-runtime] Populate module.children with the modules a file loads, matching Node (#16368)
  • [jest-runtime] Provide import.meta.resolve and import.meta.jest in data: URI modules, accept any-case mediatype parameters, and use Node's error codes for invalid data: URIs (#16368)
  • [jest-runtime] Key ES modules by full URL, so query and fragment suffixes create the same module instances as Node and show up in import.meta.url (#16375)
  • [jest-runtime] Share modules between overlapping graphs when a CommonJS module require()s an ES module mid-load, instead of evaluating shared dependencies twice (#16375)
  • [jest-runtime] Throw ERR_REQUIRE_CYCLE_MODULE like Node when a CommonJS module require()s an ES module that is still being loaded, instead of evaluating the module a second time (#16366)
  • [jest-runtime] Key builtin modules in the ESM registry by one canonical specifier (#16341)
  • [jest-runtime] import.meta.resolve() for a builtin uses its node: specifier (#16341)
  • [jest-runtime] Fall back to native ESM when a .js file contains ESM syntax but has no "type":"module" marker (#16152)
  • [jest-runtime] Allow require() of ESM-marked files on Node < 24.9 via transform fallback (#16244)
  • [jest-runtime, @jest/transform] Surface actionable ERR_REQUIRE_ESM error for files with untransformed ESM syntax instead of the generic "unexpected token" message (#16244)
  • [jest-runtime] Support older test environments whose moduleMocker does not implement clearMocksOnScope (#16169)
  • [jest-runtime] Apply jest.unstable_mockModule when the mocked file itself is require()d, not only when it is imported as a dependency (#16389)
  • [jest-runtime] Apply jest.unstable_mockModule to statically imported data: URIs on Node 24.9+, matching dynamic import() (#16389)
  • [jest-runtime] Run an async jest.unstable_mockModule factory once per module instead of twice, and fail the import instead of crashing the worker when the factory rejects (#16389)
  • [jest-runtime] Hide a require(esm) module that failed to evaluate from require.cache, as Node does, instead of exposing a namespace with uninitialized bindings (#16389)
  • [jest-runtime] Strip the byte-order mark when importing a JSON module, matching require() and Node (#16389)
  • [jest-runtime] Throw ERR_REQUIRE_ASYNC_MODULE when require(esm) runs under an async-only custom resolver, instead of silently resolving with the default resolver (#16389)
  • [jest-runtime] Parse imported JSON modules with the test realm's JSON, so their objects pass instanceof Object inside the test like require()d JSON does (#16389)
  • [jest-runtime] Accept every file: URL string in the sandboxed module.createRequire, including one with a localhost authority, as Node does (#16389)
  • [jest-runtime] Point at {virtual: true} when jest.mock or jest.unstable_mockModule is given a module that cannot be resolved (#16389)
  • [jest-reporters] Fix coverage report table formatting in CI/GitHub Actions environments where process.stdout.columns is undefined by falling back to the COLUMNS env var or 80 columns in CI, preserving existing behaviour in other non-TTY environments (#16227)
  • [jest-runtime] Support CJS-in-ESM exports via "module.exports" named exports (#16277)
  • [jest-snapshot] Keep a skipped or failed test's hinted snapshots, instead of reporting them obsolete (#16348)
  • [jest-util] Stop globsToMatcher reusing a cached matcher compiled with different picomatch options, and keep its dot: true default when dot is passed as undefined (#16381)
  • [pretty-format] Move the react-is aliases into the @jest scope, so they cannot be shadowed by unrelated packages published under the alias names (#16333)

Chore & Maintenance

  • [docs] Document the intentional divergences from Node's module system in the ECMAScript Modules page (#16368)
  • [docs] Note deprecation of react-test-renderer in React Native tutorial and pretty-format README (#16294)
  • [docs] Use @testing-library/react-native in the React Native tutorial instead of the deprecated react-test-renderer (#16318)
  • [babel-jest, @jest/transform] Update babel-plugin-istanbul to v8 (#16049)
  • [jest-config, @jest/reporters, jest-runtime] Update glob to v13 (#16397)
  • [jest-haste-map] Refactor massive class into multiple files (#16180)
  • [jest-haste-map] Drop walker dependency; replace hand-rolled directory recursion in the JS crawler and watcher startup with fdir (#16187)
  • [jest-haste-map] Reuse cached metadata for files whose haste name is a known duplicate, instead of re-reading and re-parsing them on every startup (#16351)
  • [jest-haste-map] Cache the watchman socket path and replace the watchman --version probe with get-sockname, so warm runs spawn no watchman processes (#16386)
  • [jest-resolve] Store the per-directory package-type lookup in the cache it reads, so it actually memoizes (#16369)
  • [jest-resolve, jest-runtime] Cut repeated work on the resolution hot path: hoist the platform-extension list to construction, memoize isCoreModule and the options cache-key serialization, skip mapper preparation when no moduleNameMapper is configured, run each mapper regex once, and stop re-parsing NODE_OPTIONS on every default-resolver call (#16371)
  • [jest-resolve] Cut warm resolution cost to about a third: reuse one unrs-resolver factory per options shape instead of cloning per resolution, compose the factory cache key from per-array cached strings instead of serializing options, and stop constructing an Error for misses that findNodeModule swallows; add a __benchmarks__ suite for the default resolver (#16373)
  • [jest-runner, @jest/source-map] Replace source-map-support with an implementation in @jest/source-map (#16327)
  • [jest-snapshot] Load babel, semver and synckit lazily, so requiring the package (which every test process does through @jest/expect) no longer loads ~200 modules that only writing inline snapshots needs (#16387)
  • [jest-runtime] Reduce per-require overhead: skip module ID resolution when no mock can apply, answer core modules before probing for a manual mock, share one require.cache proxy across modules, and cache empty files (#16376)
  • [@jest/source-map] Deprecate getCallsite in favour of SourceMapSupport#getCallsite (#16327)
  • [jest-runtime] Avoid magical null value in ESM loader (#16160)

New Contributors

Full Changelog: v30.4.2...v30.5.0

30.4.1

Features

  • [jest-config, jest-core, jest-runner, jest-schemas, jest-types] Allow custom runner configuration options via tuple format ['runner-path', {options}] (#16141)

Fixes

  • [jest-runtime] Align CJS-from-ESM default export with Node: module.exports is always the ESM default, __esModule unwrapping is no longer applied (#16143)

Full Changelog: v30.4.0...v30.4.1

30.4.0

Big release! 😀

Main feature is a rewrite of our custom runtime in preparation for stabilisation of native support of ESM. As part of that work require(esm) module is now supported on Node 24.9+ (still requires --experimental-vm-modules like before).

In addition we now support fake timers for the recently released Temporal API in Node v26.

React 19 is also supported properly in pretty-format, meaning snapshots of React components now work like they should.

Due to all the changes, there might be regressions that snuck in. Please report them!

Full list of changes below

Features

  • [babel-jest] Support collecting coverage from .mts, .cts (and other) files (#15994)
  • [jest-circus, jest-cli, jest-config, jest-core, jest-jasmine2, jest-types] Add --collect-tests flag to discover and list tests without executing them (#16006)
  • [jest-config, jest-runner, jest-worker] Add workerGracefulExitTimeout config option to control how long workers are given to exit before being force-killed (#15984)
  • [jest-config] Add support for jest.config.mts as a valid configuration file (#16005)
  • [jest-config, jest-core, jest-reporters, jest-runner] verbose and silent can now be set per-project; the project-level value overrides the global value for that project's tests (#16133)
  • [@jest/fake-timers] Accept Temporal.Duration in jest.advanceTimersByTime() and jest.advanceTimersByTimeAsync() (#16128)
  • [@jest/fake-timers] Accept Temporal.Instant and Temporal.ZonedDateTime in jest.setSystemTime() and useFakeTimers({now}) (#16128)
  • [@jest/fake-timers] Support faking Temporal.Now.* (#16131)
  • [jest-mock] Add clearMocksOnScope(scope) on ModuleMocker for clearing every mock function exposed on a scope object (#16088)
  • [jest-resolve] Add canResolveSync() on Resolver so callers can detect when a user-configured resolver only exports an async hook (#16064)
  • [jest-runtime] Use synchronous evaluate() for ES modules without top-level await on Node versions that support it (v24.9+), and prefer the synchronous transform path when a sync transformer is configured (#16062)
  • [jest-runtime] Support require() of ES modules on Node v24.9+ (#16074)
  • [jest-runtime] Validate TC39 import attributes (with { type: 'json' }) on ESM imports (#16127)
  • [@jest/transform] Add canTransformSync(filename) on ScriptTransformer so callers can pick the sync vs async transform path (#16062)
  • [jest-util] Add isError helper (#16076)
  • [pretty-format] Support React 19 (#16123)

Fixes

  • [expect-utils] Fix toStrictEqual failing on structuredClone results due to cross-realm constructor mismatch (#15959)
  • [@jest/expect-utils] Prevent toMatchObject/subset matching from throwing when encountering exotic iterables (#15952)
  • [fake-timers] Convert Date to milliseconds before passing to @sinonjs/fake-timers (#16029)
  • [jest] Export GlobalConfig and ProjectConfig TypeScript types (#16132)
  • [jest-circus] Prevent crash when asyncError is undefined for non-Error throws (#16003)
  • [jest-circus, jest-jasmine2] Include Error.cause in JSON failureMessages output (#15967)
  • [jest-config] Fix preset path resolution on Windows when the preset uses subpath exports (#15961)
  • [jest-config] Allow collectCoverage and coverageProvider in project config without a validation warning (#16132)
  • [jest-config] Project config validator now emits "is not supported in an individual project configuration" instead of "probably a typing mistake" for known global-only options (#16132)
  • [jest-environment-node] Fix --localstorage-file warning on Node 25+ (#16086)
  • [jest-reporters] Apply global coverage threshold to unmatched pattern files in addition to glob/path thresholds (#16137)
  • [jest-reporters, jest-runner, jest-runtime, jest-transform] Fix coverage report not showing correct code coverage when using projects config option (#16140)
  • [jest-runtime] Resolve expect and @jest/expect from the internal module registry so test-file imports share the same JestAssertionError as the global expect (#16130)
  • [jest-runtime] Improve CJS-from-ESM interop: __esModule/Babel default unwrap, broader named-export coverage, and shared CJS singleton across importers (#16050)
  • [jest-runtime] Load .js files with ESM syntax but no "type":"module" marker as native ESM (#16050)
  • [jest-runtime] Extend the .js-with-ESM-syntax fallback to require() on Node v24.9+ - falls back to require(esm) when the CJS parser rejects ESM syntax (#16078)
  • [jest-runtime] Fix deadlocks and double-evaluation in concurrent ESM and wasm imports (#16050)
  • [jest-runtime] Fix error when require() is called after the Jest environment has been torn down (#15951)
  • [jest-runtime] Fix missing error when import() is called after the Jest environment has been torn down (#16080)
  • [jest-runtime] Fix virtual unstable_mockModule registrations not respected in ESM (#16081)
  • [jest-runtime] Apply moduleNameMapper when resolving modules with require.resolve() and the paths option (#16135)

Chore & Maintenance

  • [@jest/fake-timers] Upgrade @sinonjs/fake-timers (#16139)
  • [jest-runtime] Use synchronous linkRequests / instantiate for ESM linking on Node v24.9+ (#16063)

New Contributors

Full Changelog: v30.3.0...v30.4.0

30.3.0

Features

  • [jest-config] Add defineConfig and mergeConfig helpers for type-safe Jest config (#15844)
  • [jest-fake-timers] Add setTimerTickMode to configure how timers advance
  • [*] Reduce token usage when run through LLMs (3f17932)

Fixes

  • [jest-config] Keep CLI coverage output when using --json with --outputFile (#15918)
  • [jest-mock] Use Symbol from test environment (#15858)
  • [jest-reporters] Fix issue where console output not displayed for GHA reporter even with silent: false option (#15864)
  • [jest-runtime] Fix issue where user cannot utilize dynamic import despite specifying --experimental-vm-modules Node option (#15842)
  • [jest-test-sequencer] Fix issue where failed tests due to compilation errors not getting re-executed even with --onlyFailures CLI option (#15851)
  • [jest-util] Make sure process.features.require_module is false (#15867)

Chore & Maintenance

  • [*] Replace remaining micromatch uses with picomatch
  • [deps] Update to sinon/fake-timers v15
  • [docs] Update V30 migration guide to notify users on jest.mock() work with case-sensitive path (#15849)
  • Updated Twitter icon to match the latest brand guidelines (#15869)

30.2.0

Chore & Maintenance

  • [*] Update example repo for testing React Native projects (#15832)
  • [*] Update jest-watch-typeahead to v3 (#15830)

Features

  • [jest-environment-jsdom-abstract] Add support for JSDOM v27 (#15834)

Fixes

  • [babel-jest] Export the TransformerConfig interface (#15820)
  • [jest-config] Fix jest.config.ts with TS loader specified in docblock pragma (#15839)

30.1.0

Features

  • [jest-leak-detector] Configurable GC aggressiveness regarding to V8 heap snapshot generation (#15793)
  • [jest-runtime] Reduce redundant ReferenceError messages
  • [jest-core] Include test modules that failed to load when --onlyFailures is active

Fixes

  • `[jest-snapshot-utils] Fix deprecated goo.gl snapshot guide link not getting replaced with fully canonical URL (#15787)
  • [jest-circus] Fix it.concurrent not working with describe.skip (#15765)
  • [jest-snapshot] Fix mangled inline snapshot updates when used with Prettier 3 and CRLF line endings
  • [jest-runtime] Importing from @jest/globals in more than one file no longer breaks relative paths (#15772)

Chore

  • [expect] Update docblock for toContain() to display info on substring check (#15789)

30.0.5 (from changelog)

Features

  • [jest-config] Allow testMatch to take a string value
  • [jest-worker] Let workerIdleMemoryLimit accept 0 to always restart worker child processes

Fixes

  • [expect] Fix bigint error (#15702)

30.0.2

What's Changed

Fixes

  • [jest-matcher-utils] Make 'deepCyclicCopyObject' safer by setting descriptors to a null-prototype object (#15689)
  • [jest-util] Make garbage collection protection property writable (#15689)

Full Changelog: https://github.com/jestjs/jest/blob/main/CHANGELOG.md

30.0.1

What's Changed

Features

  • [jest-resolver] Implement the defaultAsyncResolver (#15679)

Fixes

  • [jest-resolver] Resolve builtin modules correctly (#15683)
  • [jest-environment-node, jest-util] Avoid setting globals cleanup protection symbol when feature is off (#15684)

Chore & Maintenance

  • [*] Remove and deprecate jest-repl package (#15673)
  • [jest-resolver] Replace custom isBuiltinModule with node's isBuiltin (#15685)

New Contributors

Full Changelog: https://github.com/jestjs/jest/blob/main/CHANGELOG.md

30.0.0

Today we are happy to announce the release of Jest 30. This release features a substantial number of changes, fixes, and improvements. While it is one of the largest major releases of Jest ever, we admit that three years for a major release is too long. In the future, we are aiming to make more frequent major releases to keep Jest great for the next decade.

If you want to skip all the news and just get going, run npm install jest@^30.0.0 and follow the migration guide: Upgrading from Jest 29 to 30.

Read the full blog post

Features

  • [*] Renamed globalsCleanupMode to globalsCleanup and --waitNextEventLoopTurnForUnhandledRejectionEvents to --waitForUnhandledRejections
  • [expect] Add ArrayOf asymmetric matcher for validating array elements. (#15567)
  • [babel-jest] Add option excludeJestPreset to allow opting out of babel-preset-jest (#15164)
  • [expect] Revert #15038 to fix expect(fn).toHaveBeenCalledWith(expect.objectContaining(...)) when there are multiple calls (#15508)
  • [jest-circus, jest-cli, jest-config] Add waitNextEventLoopTurnForUnhandledRejectionEvents flag to minimise performance impact of correct detection of unhandled promise rejections introduced in #14315 (#14681)
  • [jest-circus] Add a waitBeforeRetry option to jest.retryTimes (#14738)
  • [jest-circus] Add a retryImmediately option to jest.retryTimes (#14696)
  • [jest-circus, jest-jasmine2] Allow setupFilesAfterEnv to export an async function (#10962)
  • [jest-circus, jest-test-result] Add startedAt timestamp in TestCaseResultObject within onTestCaseResult (#15145)
  • [jest-cli] Export buildArgv (#15310)
  • [jest-config] [BREAKING] Add mts and cts to default moduleFileExtensions config (#14369)
  • [jest-config] [BREAKING] Update testMatch and testRegex default option for supporting mjs, cjs, mts, and cts (#14584)
  • [jest-config] Loads config file from provided path in package.json (#14044)
  • [jest-config] Allow loading jest.config.cts files (#14070)
  • [jest-config] Show rootDir in error message when a preset fails to load (#15194)
  • [jest-config] Support loading TS config files using esbuild-register via docblock loader (#15190)
  • [jest-config] Allow passing TS config loader options via docblock comment (#15234)
  • [jest-config] If Node is running with type stripping enabled, do not require a TS loader (#15480)
  • [@jest/core] Group together open handles with the same stack trace (#13417, & #14789)
  • [@jest/core] Add perfStats to surface test setup overhead (#14622)
  • [@jest/core] [BREAKING] Changed --filter to accept an object with shape { filtered: Array<string> } to match documentation (#13319)
  • [@jest/core] Support --outputFile option for --listTests (#14980)
  • [@jest/core] Stringify Errors properly with --json flag (#15329)
  • [@jest/core, @jest/test-sequencer] [BREAKING] Exposes globalConfig & contexts to TestSequencer (#14535, & #14543)
  • [jest-each] Introduce %$ option to add number of the test to its title (#14710)
  • [@jest/environment] [BREAKING] Remove deprecated jest.genMockFromModule() (#15042)
  • [@jest/environment] [BREAKING] Remove unnecessary defensive code (#15045)
  • [jest-environment-jsdom] [BREAKING] Upgrade JSDOM to v22 (#13825)
  • [@jest/environment-jsdom-abstract] Introduce new package which abstracts over the jsdom environment, allowing usage of custom versions of JSDOM (#14717)
  • [jest-environment-node] Update jest environment with dispose symbols Symbol (#14888 & #14909)
  • [expect, @jest/expect] [BREAKING] Add type inference for function parameters in CalledWith assertions (#15129)
  • [@jest/expect-utils] Properly compare all types of TypedArrays (#15178)
  • [@jest/fake-timers] [BREAKING] Upgrade @sinonjs/fake-timers to v13 (#14544 & #15470)
  • [@jest/fake-timers] Exposing new modern timers function advanceTimersToFrame() which advances all timers by the needed milliseconds to execute callbacks currently scheduled with requestAnimationFrame (#14598)
  • [jest-matcher-utils] Add SERIALIZABLE_PROPERTIES to allow custom serialization of objects (#14893)
  • [jest-mock] Add support for the Explicit Resource Management proposal to use the using keyword with jest.spyOn(object, methodName) (#14895)
  • [jest-reporters] Add support for DEC mode 2026 (#15008)
  • [jest-resolver] Support file:// URLs as paths (#15154)
  • [jest-resolve,jest-runtime,jest-resolve-dependencies] Pass the conditions when resolving stub modules (#15489)
  • [jest-runtime] Exposing new modern timers function jest.advanceTimersToFrame() from @jest/fake-timers (#14598)
  • [jest-runtime] Support import.meta.filename and import.meta.dirname (available from Node 20.11) (#14854)
  • [jest-runtime] Support import.meta.resolve (#14930)
  • [jest-runtime] [BREAKING] Make it mandatory to pass globalConfig to the Runtime constructor (#15044)
  • [jest-runtime] Add unstable_unmockModule (#15080)
  • [jest-runtime] Add onGenerateMock transformer callback for auto generated callbacks (#15433 & #15482)
  • [jest-runtime] [BREAKING] Use vm.compileFunction over vm.Script (#15461)
  • [@jest/schemas] Upgrade @sinclair/typebox to v0.34 (#15450)
  • [@jest/types] test.each(): Accept a readonly (as const) table properly (#14565)
  • [@jest/types] Improve argument type inference passed to test and describe callback functions from each tables (#14920)
  • [jest-snapshot] [BREAKING] Add support for Error causes in snapshots (#13965)
  • [jest-snapshot] Support Prettier 3 (#14566)
  • [@jest/util-snapshot] Extract utils used by tooling from jest-snapshot into its own package (#15095)
  • [pretty-format] [BREAKING] Do not render empty string children ('') in React plugin (#14470)

Fixes

  • [expect] Show AggregateError to display (#15346)
  • [*] Replace exit with exit-x (#15399)
  • [babel-plugin-jest-hoist] Use denylist instead of the deprecated blacklist for Babel 8 support (#14109)
  • [babel-plugin-jest-hoist] Do not rely on buggy Babel behaviour (#15415)
  • [expect] Check error instance type for toThrow/toThrowError (#14576)
  • [expect] Improve diff for failing expect.objectContaining (#15038)
  • [expect] Use Array.isArray to check if an array is an Array (#15101)
  • [expect] Fix Error cause assertion errors (#15339)
  • [jest-changed-files] Print underlying errors when VCS commands fail (#15052)
  • [jest-changed-files] Abort sl root call if output resembles a steam locomotive (#15053)
  • [jest-circus] [BREAKING] Prevent false test failures caused by promise rejections handled asynchronously (#14315)
  • [jest-circus] Replace recursive makeTestResults implementation with iterative one (#14760)
  • [jest-circus] Omit expect.hasAssertions() errors if a test already has errors (#14866)
  • [jest-circus, jest-expect, jest-snapshot] Pass test.failing tests when containing failing snapshot matchers (#14313)
  • [jest-circus] Concurrent tests now emit jest circus events at the correct point and in the expected order. (#15381)
  • [jest-cli] [BREAKING] Validate CLI flags that require arguments receives them (#14783)
  • [jest-config] Make sure to respect runInBand option (#14578)
  • [jest-config] Support testTimeout in project config (#14697)
  • [jest-config] Support coverageReporters in project config (#14697)
  • [jest-config] Allow reporters in project config (#14768)
  • [jest-config] Allow Node16/NodeNext/Bundler moduleResolution in project's tsconfig (#14739)
  • [@jest/create-cache-key-function] Correct the return type of createCacheKey (#15159)
  • [jest-each] Allow $keypath templates with null or undefined values (#14831)
  • [@jest/expect-utils] Fix comparison of DataView (#14408)
  • [@jest/expect-utils] [BREAKING] exclude non-enumerable in object matching (#14670)
  • [@jest/expect-utils] Fix comparison of URL (#14672)
  • [@jest/expect-utils] Check Symbol properties in equality (#14688)
  • [@jest/expect-utils] Catch circular references within arrays when matching objects (#14894)
  • [@jest/expect-utils] Fix not addressing to Sets and Maps as objects without keys (#14873)
  • [jest-haste-map] Fix errors or clobbering with multiple hasteImplModulePaths (#15522)
  • [jest-leak-detector] Make leak-detector more aggressive when running GC (#14526)
  • [jest-runtime] Properly handle re-exported native modules in ESM via CJS (#14589)
  • [jest-runtime] Refactor _importCoreModel so required core module is consistent if modified while loading (#15077)
  • [jest-schemas, jest-types] [BREAKING] Fix type of testFailureExitCode config option(#15232)
  • [jest-util] Make sure isInteractive works in a browser (#14552)
  • [pretty-format] [BREAKING] Print ArrayBuffer and DataView correctly (#14290)
  • [pretty-format] Fixed a bug where "anonymous custom elements" were not being printed as expected. (#15138)
  • [jest-cli] When specifying paths on the command line, only match against the relative paths of the test files (#12519)
    • [BREAKING] Changes testPathPattern configuration option to testPathPatterns, which now takes a list of patterns instead of the regex.
    • [BREAKING] --testPathPattern is now --testPathPatterns
    • [BREAKING] Specifying testPathPatterns when programmatically calling watch must be specified as new TestPathPatterns(patterns), where TestPathPatterns can be imported from @jest/pattern
  • [jest-reporters, jest-runner] Unhandled errors without stack get correctly logged to console (#14619)
  • [jest-util] Always load mjs files with import (#15447)
  • [jest-worker] Properly handle a circular reference error when worker tries to send an assertion fails where either the expected or actual value is circular (#15191)
  • [jest-worker] Properly handle a BigInt when worker tries to send an assertion fails where either the expected or actual value is BigInt (#15191)
  • [expect] Resolve issue where ObjectContaining matched non-object values. ([#15463])(#15463).
    • Adds a conditional/check to ensure the argument passed to expect is an object.
    • Add unit tests for new ObjectContaining behavior.
    • Remove invalid/wrong test case assertions for ObjectContaining.
  • [jest-worker] Addresses incorrect state on exit (#15610)

Performance

  • [*] [BREAKING] Bundle all of Jest's modules into index.js (#12348, #14550 & #14661)
  • [jest-haste-map] Only spawn one process to check for watchman installation (#14826)
  • [jest-runner] Better cleanup source-map-support after test to resolve (minor) memory leak (#15233)
  • [jest-circus, jest-environment-node, jest-repl, jest-runner, jest-util] Cleanup global variables on environment teardown to reduce memory leaks (#15215 & #15636 & #15643)

Chore & Maintenance

  • [jest-environment-jsdom, jest-environment-jsdom-abstract] Increased version of jsdom to ^26.0.0 (#15325CVE-2024-37890)
  • [*] Increase version of micromatch to ^4.0.7 (#15082)
  • [*] [BREAKING] Drop support for Node.js versions 14, 16, 19, 21 and 23 (#14460, #15118, #15623, #15640)
  • [*] [BREAKING] Drop support for typescript@4.3, minimum version is now 5.4 (#14542, #15621)
  • [*] Depend on exact versions of monorepo dependencies instead of ^ range (#14553)
  • [*] [BREAKING] Add ESM wrapper for all of Jest's modules (#14661)
  • [*] [BREAKING] Upgrade to glob@10 (#14509)
  • [*] Use TypeError over Error where appropriate (#14799)
  • [docs] Fix typos in CHANGELOG.md and packages/jest-validate/README.md (#14640)
  • [docs] Don't use alias matchers in docs (#14631)
  • [babel-jest, babel-preset-jest] [BREAKING] Increase peer dependency of @babel/core to ^7.11 (#14109)
  • [babel-jest, @jest/transform] Update babel-plugin-istanbul to v6 (#15156)
  • [babel-plugin-jest-hoist] Move unnecessary dependencies to devDependencies (#15010)
  • [expect] [BREAKING] Remove .toBeCalled(), .toBeCalledTimes(), .toBeCalledWith(), .lastCalledWith(), .nthCalledWith(), .toReturn(), .toReturnTimes(), .toReturnWith(), .lastReturnedWith(), .nthReturnedWith() and .toThrowError() matcher aliases (#14632)
  • [jest-cli, jest-config, @jest/types] [BREAKING] Remove deprecated --init argument (#14490)
  • [jest-config, @jest/core, jest-util] Upgrade ci-info (#14655)
  • [jest-mock] [BREAKING] Remove MockFunctionMetadataType, MockFunctionMetadata and SpyInstance types (#14621)
  • [@jest/reporters] Upgrade istanbul-lib-source-maps (#14924)
  • [jest-schemas] Upgrade @sinclair/typebox (#14775)
  • [jest-transform] Upgrade write-file-atomic (#14274)
  • [jest-util] Upgrade picomatch to v4 (#14653 & #14885)
  • [docs] Append to NODE_OPTIONS, not overwrite ([#14730](https://github.com/jestjs/jest/pull/14730))
  • [docs] Updated .toHaveBeenCalled() documentation to correctly reflect its functionality (#14842)
  • [docs] Link NestJS documentation on testing with Jest (#14940)
  • [docs] Revised documentation for .toHaveBeenCalled() to accurately depict its functionality. (#14853)
  • [docs] Removed ExpressJS reference link from documentation due to dead link (#15270)
  • [docs] Correct broken links in docs (#15359)

See the CHANGELOG.

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ jest-matcher-utils (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ jest-message-util (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

30.5.0

On a personal note: King Harald V of Norway passed away this morning. He ascended the throne 35 years ago, two months before I was born. This release is dedicated to his memory. Hvil i fred 🇳🇴


This is a big release. It touches jest-runtime, jest-resolve and jest-haste-map in many places, and with this many changes there might be regressions 😬. If your suite behaves differently after upgrading, please open an issue.

Highlights

whenCalledWith

Mock functions can now configure return values per argument list, contributed by @timkindberg (#16053):

const fn = jest.fn();
fn.whenCalledWith('apple').mockReturnValue('red');
fn.whenCalledWith('banana').mockReturnValue('yellow');
fn.whenCalledWith(expect.any(Number)).mockReturnValue('numeric');

fn('apple'); // 'red'
fn('banana'); // 'yellow'
fn(42); // 'numeric'
fn('grape'); // undefined

The returned object is a real Mock, so mockReturnValueOnce, mockResolvedValue, mockImplementation etc. all chain here too. Argument slots accept literals or any asymmetric matcher, with the same equality semantics as toHaveBeenCalledWith(). Calls that match nothing fall through to the base mock. See the Mock Functions docs for matching and precedence details.

Describe-level retries

jest.retryTimes() can now retry a whole describe block instead of a single test, contributed by @soltonigiri (#16322). Each attempt reruns the block's beforeAll/afterAll hooks, child tests and nested describes, which helps when tests in a block depend on shared state:

describe('workflow', () => {
  jest.retryTimes(3, {entireDescribe: true});

  test('first step', () => {});
  test('second step', () => {}); // a failure retries the entire block
});

New file watcher

The non-watchman path of jest-haste-map is rewritten. @parcel/watcher replaces the homegrown NodeWatcher and FSEventsWatcher (#16188), and fdir replaces the hand-rolled directory recursion in the crawler (#16187). A batch of fixes also makes watching and indexing survive locked files on Windows, watchman failures, and duplicate manual mocks (#16295, #16358, #16355, #16360).

If you can, please run your suite with --no-watchman (in and out of watch mode) to exercise the new crawler and watchers, and report anything odd 👍

Long-requested dependency updates

  • babel-plugin-istanbul is updated to v8 (#16049)
  • glob is updated to v13 (#16397)
  • source-map-support is replaced with an implementation in @jest/source-map (#16327). This fixes a memory leak where source-map-support's process-global caches pinned every finished test file's sandbox. Source maps also survive environment teardown, --testLocationInResults looks up the right column, and scheme-prefixed sources like webpack:/// are kept as-is.

Performance

  • Warm module resolution costs about a third of what it did, and repeated work is gone from the resolution hot path (#16373, #16371).
  • Per-require overhead in jest-runtime is cut: module ID resolution is skipped when no mock can apply, and core modules answer before the manual-mock probe (#16376).
  • jest-snapshot loads babel, semver and synckit lazily, so every test process loads ~200 fewer modules (#16387).
  • jest-haste-map caches the watchman socket path, so warm runs spawn no watchman processes (#16386), and reuses cached metadata for duplicated haste names instead of re-parsing them on every startup (#16351).

More new APIs

  • Snapshot failures expose the .snap file path as matcherResult.snapshotPath in failureDetails (#16374).
  • --collectTests expands test.each/describe.each cases and reports per-status counts plus a summary line that matches a real run (#16259).
  • AggregateError inner errors and nested cause chains render with code frames and per-level indentation, and are included in --json output, retryReasons and reporter annotations (#16316).

ESM

A long list of fixes brings jest-runtime's module system closer to Node's:

  • Automocking and manual __mocks__ files now apply to ESM on Node 24.9+. Static imports, dynamic import() and require() of an ESM file generate an automock from the real module's namespace instead of failing with "Attempting to import a mock without a factory" (#16391).
  • Many jest.unstable_mockModule gaps are closed: mocks apply when the mocked file is require()d directly, async factories run once and fail the import instead of crashing the worker 😅, and mocks made inside jest.isolateModules stay scoped to that block (#16389, #16365).
  • require(esm), CJS/ESM interop, import.meta, data: URIs and error ordering now match Node in dozens of edge cases. See the Fixes section for the full list (#16364 through #16391).
  • The module-sync export condition resolves, so packages that expose their ESM entry point for require() load the same file Node picks (#16336).

The intentional divergences from Node's module system are now documented on the ECMAScript Modules page (#16368).

Resolver

  • The default resolver honors Node's --preserve-symlinks / NODE_PRESERVE_SYMLINKS (#16260).
  • moduleNameMapper applies to both spellings of core module specifiers (fs and node:fs), and builtins that only exist prefixed (node:sqlite, node:test) resolve asynchronously (#16390, #16388).
  • A user resolver can be written as an ES module (#16332).

On top of the highlights there are ~60 fixes across jest-circus, jest-haste-map, jest-config, jest-mock and the transform cache keys. See the full changelog below 😀


Features

  • [@jest/expect-utils, jest-mock] Add mockFn.whenCalledWith(...args) for configuring return values per argument list, with first-class asymmetric-matcher support (#16053)
  • [@jest/expect-utils] Export AsymmetricMatcher and FunctionParameters types (previously private to expect) (#16053)
  • [jest-circus, jest-core, jest-jasmine2, jest-test-result, jest-types] --collectTests now expands test.each/describe.each cases and reports per-status counts (skipped/todo via the new wouldRun flag for selected tests) plus a summary line that match a real run, including under --testNamePattern and .only/fdescribe focus on both the circus and jasmine2 runners (#16259)
  • [jest-circus, jest-environment, jest-runtime, jest-types] Add describe-level retries via jest.retryTimes(..., {entireDescribe: true}) (#16322)
  • [jest-circus, jest-message-util, jest-reporters, jest-types] Add retryMessages to AssertionResult and export formatErrorStack, so the retry log renders nested cause and AggregateError sections with code frames instead of serialized [cause]:/[errors]: markers (#16316)
  • [jest-circus, jest-types] Add unhandledErrorsDetailed to Circus.RunResult, so an unhandled rejection reports its cause chain and AggregateError entries with code frames instead of a pre-serialized stack (#16316)
  • [jest-haste-map] Replace NodeWatcher and FSEventsWatcher with @parcel/watcher for the non-watchman watch path (#16188)
  • [jest-resolve] Bump unrs-resolver to 1.12.1, remove jest-pnp-resolver and unnecessary checks (#15721)
  • [jest-resolve] Honor Node's --preserve-symlinks / NODE_PRESERVE_SYMLINKS in the default resolver by passing symlinks: false to unrs-resolver (#16260)
  • [jest-runtime] Apply automocking and manual __mocks__ files to synchronously evaluable ESM graphs on Node 24.9+ - static imports, dynamic import() and require() of an ESM file now generate an automock from the real module's namespace instead of failing with "Attempting to import a mock without a factory". Graphs that need async evaluation (top-level await) or an async-only resolver or transformer still throw (#16391)
  • [jest-runtime] Route process.getBuiltinModule through the sandbox, so it returns the sandbox process and the hooked node:module instead of the host's (#16391)
  • [jest-runtime] Throw an actionable error from module.register() and module.registerHooks() inside a test - the hooks attached to the loader running Jest itself, never saw the sandboxed requires they were meant for, and stayed registered for every later test file in the worker (#16391)
  • [jest-runtime] Surface resolution and import-attribute errors in an ESM graph before executing any of its CJS dependencies on Node 24.9+, matching Node's run-nothing-on-a-broken-graph behavior; the legacy loader on older versions keeps its linking-time execution order (#16391)
  • [jest-runtime] Throw ERR_SOURCE_PHASE_NOT_DEFINED with an actionable message for import source and import.source(), instead of failing at instantiation with V8's bare "Source phase import object is not defined" (#16391)
  • [jest-runtime] Emit the JSON-without-import-attribute deprecation warning once per test file instead of once per worker, so it is no longer silently swallowed for every file after the first (#16391)
  • [jest-runtime] Set import.meta.main to true in the test file and false in every module it loads, matching Node 24+ (#16367)
  • [jest-runtime] Resolve the module-sync export condition, so a package that exposes its ESM entry point for require() loads the same file Node would (#16336)
  • [jest-snapshot] Add external snapshot paths to custom reporter failure details (#16374)

Fixes

  • [jest-console, jest-reporters] CustomConsole now buffers console output so TestResult.console is populated for reporters when verbose is enabled, while GitHubActionsReporter avoids replaying buffered output in verbose mode (#16155)
  • [expect, jest-message-util, jest-pattern, jest-regex-util, jest-util] Revert node: protocol imports to restore webpack/browser-bundle compatibility (#16167)
  • [expect] Widen toMatchObject and objectContaining parameter type from Record<string, unknown> to object so class instances are accepted (#16196)
  • [jest-circus] Call a generator test body with the shared test context, so this matches what a regular test function receives (#16347)
  • [jest-circus] Capture the error listeners of the parent process instead of the in-sandbox process, so listeners registered before the test file survive teardown and sandbox listeners no longer leak onto the parent (#16347)
  • [jest-circus] Clear currentlyRunningTest after skipped and todo tests (#16342)
  • [jest-circus] Prevent late done() callbacks from affecting later test or hook invocations (#16343)
  • [jest-circus, jest-jasmine2] Honor --expand when formatting node:assert failures, instead of always collapsing the diff (#16347)
  • [jest-circus, jest-jasmine2, jest-message-util] Serialize the inner errors of an AggregateError into failureMessages, retryReasons and unhandledErrors, so --json output and reporter annotations include them (#16316)
  • [jest-circus, jest-snapshot] Keep snapshot state and counts correct when a test retries (#16344)
  • [@jest/create-cache-key-function] Include the caller support flags in the generated key, so a transformer that emits ESM or CJS based on them no longer shares one cache entry between the two (#16331)
  • [@jest/create-cache-key-function] Include the stringified project config in the generated key, so editing a transformer's own settings invalidates what it cached (#16331)
  • [@jest/transform] Include the caller support flags in a transform's cache key, so a file transformed both as ESM and as CJS no longer serves one shape's output for the other (#16331)
  • [jest-config] Add missing findRelatedTests, outputFile, and replname entries to ValidConfig so they no longer trigger spurious "Unknown option" warnings (#16224)
  • [jest-config] Use --config for the global config when multiple --projects are specified (#16273)
  • [jest-core] Serialize bigint values in --json and --outputFile output as their literal form (4n), instead of failing the run with TypeError: Do not know how to serialize a BigInt (#16338)
  • [jest-core] Do not report a CustomGC async resource (used by N-API addons such as napi-rs for per-isolate GC bookkeeping) as an open handle, since it is napi_unref'd by the addon and can never keep the event loop alive (#16379)
  • [jest-each] Keep a $&, $`, $' or $$ inside a %p param value out of the replacement, so the title shows the value instead of the text around it (#16338)
  • [jest-each] Interpolate a bigint into a %j title as its literal form ("4n") at any depth, instead of throwing TypeError: Do not know how to serialize a BigInt while collecting the tests (#16338)
  • [jest-environment, jest-runtime] Bind sandboxInjectedGlobals to the right values when injectGlobals is false, instead of shifting every one of them by a position (#16377)
  • [jest-environment-node, jest-util] Only warn about a conflicting globalsCleanup mode when one was explicitly configured, and follow the mode that is actually in effect (#16323)
  • [jest-environment-node, jest-util] Stop resolving lazy globals when setting up an environment, so Node 26's builtin module globals are no longer loaded (and no longer emit their deprecation warnings) for every test file (#16324)
  • [jest-haste-map] Keep watch mode alive when an outside process briefly makes a file unreadable on Windows, instead of tearing the watcher down on EPERM (#16295)
  • [jest-haste-map] Keep indexing when an outside process holds a file open on Windows, instead of failing the whole crawl on EPERM (#16358)
  • [jest-haste-map] Keep a duplicated manual mock resolving when the file it pointed at is deleted in watch mode (#16360)
  • [jest-haste-map] Shut the worker farm down when a duplicate manual mock aborts the build under throwOnModuleCollision (#16354)
  • [jest-haste-map] Attach the watchman client's error listener before the first command, so a watchman failure falls back to the node crawler instead of crashing on an unhandled error event, and always end the client (#16355)
  • [jest-haste-map] Stop delivering watch events after WatchmanWatcher is closed, and route its warnings through the configured console (#16355)
  • [jest-haste-map] Restore the nested duplicates index correctly in ModuleMap.fromJSON, so a haste collision reported inside a test worker raises DuplicateHasteCandidatesError instead of a TypeError (#16353)
  • [jest-haste-map] Match watched files on a full extension, so moduleFileExtensions: ['js'] no longer accepts foo.mjs (#16352)
  • [jest-haste-map] Delimit the fields that make up the haste map cache key, so two different option sets cannot hash to the same cache file (#16352)
  • [jest-message-util] Print the inner errors of an AggregateError thrown inside a test (#16316)
  • [jest-message-util] Indent nested cause and AggregateError sections of a test failure by one level per depth, so the nesting is legible instead of rendering flat (#16316)
  • [jest-message-util] Color stack traces line by line so blank lines stay blank (#16316)
  • [jest-message-util] Detect Jest's own frames without assuming the checkout directory's name, and cover @jest/* packages, so stack traces and code frames point at user code (#16326)
  • [jest-mock] mockResolvedValue / mockRejectedValue now see all overload return types, so a Promise-returning overload survives even when a later overload returns a non-Promise (e.g. pg.Client['end']) (#16237)
  • [@jest-environment/jsdom-abstract] Make @types/jsdom a peer dependency (#16166)
  • [jest-mock] Remove the leftover own accessor descriptor when restoring a spyOn of an inherited getter or setter, so the instance keeps reflecting the prototype (#16226)
  • [jest-resolve] Include extensionsToTreatAsEsm in the shouldLoadAsEsm cache key, so projects with different extension lists don't read each other's answers (#16369)
  • [jest-resolve] Make getModuleIDAsync build and cache data: URI module IDs the same way as getModuleID (#16370)
  • [jest-resolve] Keep the node: prefix when resolving a core module asynchronously, so a builtin that only exists prefixed (node:sea, node:sqlite, node:test, node:test/reporters) resolves instead of failing as a missing bare package (#16388)
  • [jest-resolve] Look up manual mocks for node: protocol specifiers under the unprefixed name they are stored as (#16388)
  • [jest-resolve] Apply moduleNameMapper consistently to both spellings of core module specifiers (fs vs node:fs) (#16390)
  • [jest-resolve] Keep virtual and ordinary mock module IDs isolated across test files (#16296)
  • [jest-resolve] Guard missing require.resolve.paths (#16052)
  • [jest-resolve, jest-config, jest-runner] Support a user resolver written as an ES module (#16332)
  • [jest-resolve, jest-runtime] Throw the CJS parse error for ESM syntax in a "type": "commonjs" package or a .cjs file instead of loading it as ESM, matching Node (#16368)
  • [@jest/source-map] Keep source map sources that name a scheme, such as webpack:///, instead of resolving them into a path that does not exist (#16327)
  • [@jest/source-map] Look up --testLocationInResults positions at the right column, and keep a mapping to the first column instead of discarding it (#16327)
  • [@jest/source-map] Warn when a source map cannot be parsed, instead of silently leaving its frames untranslated (#16327)
  • [jest-runner, @jest/source-map] Keep a source-mapped stack for an error thrown after the test environment was torn down (#16327)
  • [jest-runtime, @jest/source-map] Keep source maps past teardown and past the next test file's install, so a stack from a file no earlier stack mentioned still points at the original source (#16330)
  • [jest-runtime] Report that no coverage was collected when getAllV8CoverageInfoCopy is called after teardown, instead of returning an empty result (#16385)
  • [jest-runtime] Cache a CJS module's parsed exports before walking its re-exports, so two modules that re-export each other no longer overflow the stack when imported from ESM (#16363)
  • [jest-runtime] Keep a re-exported ES module's parse failure from marking the re-exporting CommonJS file as ESM, so module.exports = require('./dep.mjs') loads instead of failing with module is not defined (#16363)
  • [jest-runtime] Scope module mocks instantiated inside jest.isolateModules/isolateModulesAsync to that block, so a mock first imported there no longer outlives it - matching how CommonJS mocks already behave (#16365)
  • [jest-runtime] Suspend module isolation while generating an automock, so loading the real module to read its shape no longer populates the isolated registry (#16365)
  • [jest-runtime] Check a cached ES module's status before require() returns it, so a module whose evaluation threw rethrows that error and one left linked by a failed sibling is evaluated instead of returning uninitialized bindings (#16364)
  • [jest-runtime] Report the original ERR_REQUIRE_ASYNC_MODULE when a require() of a top-level-await graph is retried, instead of a spurious "concurrent import()" error (#16364)
  • [jest-runtime] Throw the evaluation error when another caller's import() of the same module failed while we awaited it, instead of resolving with the errored module (#16364)
  • [jest-runtime] Mark the result of require()ing an ES module that has a default export with __esModule: true through a live-binding facade, and serve the same object from require.cache, matching Node (#16367)
  • [jest-runtime] Provide a CommonJS module's exports under the 'module.exports' named export when imported from ESM, matching Node 23+ (#16367)
  • [jest-runtime] Give the test file itself a non-null require.main (#16367)
  • [jest-runtime] Populate module.children with the modules a file loads, matching Node (#16368)
  • [jest-runtime] Provide import.meta.resolve and import.meta.jest in data: URI modules, accept any-case mediatype parameters, and use Node's error codes for invalid data: URIs (#16368)
  • [jest-runtime] Key ES modules by full URL, so query and fragment suffixes create the same module instances as Node and show up in import.meta.url (#16375)
  • [jest-runtime] Share modules between overlapping graphs when a CommonJS module require()s an ES module mid-load, instead of evaluating shared dependencies twice (#16375)
  • [jest-runtime] Throw ERR_REQUIRE_CYCLE_MODULE like Node when a CommonJS module require()s an ES module that is still being loaded, instead of evaluating the module a second time (#16366)
  • [jest-runtime] Key builtin modules in the ESM registry by one canonical specifier (#16341)
  • [jest-runtime] import.meta.resolve() for a builtin uses its node: specifier (#16341)
  • [jest-runtime] Fall back to native ESM when a .js file contains ESM syntax but has no "type":"module" marker (#16152)
  • [jest-runtime] Allow require() of ESM-marked files on Node < 24.9 via transform fallback (#16244)
  • [jest-runtime, @jest/transform] Surface actionable ERR_REQUIRE_ESM error for files with untransformed ESM syntax instead of the generic "unexpected token" message (#16244)
  • [jest-runtime] Support older test environments whose moduleMocker does not implement clearMocksOnScope (#16169)
  • [jest-runtime] Apply jest.unstable_mockModule when the mocked file itself is require()d, not only when it is imported as a dependency (#16389)
  • [jest-runtime] Apply jest.unstable_mockModule to statically imported data: URIs on Node 24.9+, matching dynamic import() (#16389)
  • [jest-runtime] Run an async jest.unstable_mockModule factory once per module instead of twice, and fail the import instead of crashing the worker when the factory rejects (#16389)
  • [jest-runtime] Hide a require(esm) module that failed to evaluate from require.cache, as Node does, instead of exposing a namespace with uninitialized bindings (#16389)
  • [jest-runtime] Strip the byte-order mark when importing a JSON module, matching require() and Node (#16389)
  • [jest-runtime] Throw ERR_REQUIRE_ASYNC_MODULE when require(esm) runs under an async-only custom resolver, instead of silently resolving with the default resolver (#16389)
  • [jest-runtime] Parse imported JSON modules with the test realm's JSON, so their objects pass instanceof Object inside the test like require()d JSON does (#16389)
  • [jest-runtime] Accept every file: URL string in the sandboxed module.createRequire, including one with a localhost authority, as Node does (#16389)
  • [jest-runtime] Point at {virtual: true} when jest.mock or jest.unstable_mockModule is given a module that cannot be resolved (#16389)
  • [jest-reporters] Fix coverage report table formatting in CI/GitHub Actions environments where process.stdout.columns is undefined by falling back to the COLUMNS env var or 80 columns in CI, preserving existing behaviour in other non-TTY environments (#16227)
  • [jest-runtime] Support CJS-in-ESM exports via "module.exports" named exports (#16277)
  • [jest-snapshot] Keep a skipped or failed test's hinted snapshots, instead of reporting them obsolete (#16348)
  • [jest-util] Stop globsToMatcher reusing a cached matcher compiled with different picomatch options, and keep its dot: true default when dot is passed as undefined (#16381)
  • [pretty-format] Move the react-is aliases into the @jest scope, so they cannot be shadowed by unrelated packages published under the alias names (#16333)

Chore & Maintenance

  • [docs] Document the intentional divergences from Node's module system in the ECMAScript Modules page (#16368)
  • [docs] Note deprecation of react-test-renderer in React Native tutorial and pretty-format README (#16294)
  • [docs] Use @testing-library/react-native in the React Native tutorial instead of the deprecated react-test-renderer (#16318)
  • [babel-jest, @jest/transform] Update babel-plugin-istanbul to v8 (#16049)
  • [jest-config, @jest/reporters, jest-runtime] Update glob to v13 (#16397)
  • [jest-haste-map] Refactor massive class into multiple files (#16180)
  • [jest-haste-map] Drop walker dependency; replace hand-rolled directory recursion in the JS crawler and watcher startup with fdir (#16187)
  • [jest-haste-map] Reuse cached metadata for files whose haste name is a known duplicate, instead of re-reading and re-parsing them on every startup (#16351)
  • [jest-haste-map] Cache the watchman socket path and replace the watchman --version probe with get-sockname, so warm runs spawn no watchman processes (#16386)
  • [jest-resolve] Store the per-directory package-type lookup in the cache it reads, so it actually memoizes (#16369)
  • [jest-resolve, jest-runtime] Cut repeated work on the resolution hot path: hoist the platform-extension list to construction, memoize isCoreModule and the options cache-key serialization, skip mapper preparation when no moduleNameMapper is configured, run each mapper regex once, and stop re-parsing NODE_OPTIONS on every default-resolver call (#16371)
  • [jest-resolve] Cut warm resolution cost to about a third: reuse one unrs-resolver factory per options shape instead of cloning per resolution, compose the factory cache key from per-array cached strings instead of serializing options, and stop constructing an Error for misses that findNodeModule swallows; add a __benchmarks__ suite for the default resolver (#16373)
  • [jest-runner, @jest/source-map] Replace source-map-support with an implementation in @jest/source-map (#16327)
  • [jest-snapshot] Load babel, semver and synckit lazily, so requiring the package (which every test process does through @jest/expect) no longer loads ~200 modules that only writing inline snapshots needs (#16387)
  • [jest-runtime] Reduce per-require overhead: skip module ID resolution when no mock can apply, answer core modules before probing for a manual mock, share one require.cache proxy across modules, and cache empty files (#16376)
  • [@jest/source-map] Deprecate getCallsite in favour of SourceMapSupport#getCallsite (#16327)
  • [jest-runtime] Avoid magical null value in ESM loader (#16160)

New Contributors

Full Changelog: v30.4.2...v30.5.0

30.4.1

Features

  • [jest-config, jest-core, jest-runner, jest-schemas, jest-types] Allow custom runner configuration options via tuple format ['runner-path', {options}] (#16141)

Fixes

  • [jest-runtime] Align CJS-from-ESM default export with Node: module.exports is always the ESM default, __esModule unwrapping is no longer applied (#16143)

Full Changelog: v30.4.0...v30.4.1

30.4.0

Big release! 😀

Main feature is a rewrite of our custom runtime in preparation for stabilisation of native support of ESM. As part of that work require(esm) module is now supported on Node 24.9+ (still requires --experimental-vm-modules like before).

In addition we now support fake timers for the recently released Temporal API in Node v26.

React 19 is also supported properly in pretty-format, meaning snapshots of React components now work like they should.

Due to all the changes, there might be regressions that snuck in. Please report them!

Full list of changes below

Features

  • [babel-jest] Support collecting coverage from .mts, .cts (and other) files (#15994)
  • [jest-circus, jest-cli, jest-config, jest-core, jest-jasmine2, jest-types] Add --collect-tests flag to discover and list tests without executing them (#16006)
  • [jest-config, jest-runner, jest-worker] Add workerGracefulExitTimeout config option to control how long workers are given to exit before being force-killed (#15984)
  • [jest-config] Add support for jest.config.mts as a valid configuration file (#16005)
  • [jest-config, jest-core, jest-reporters, jest-runner] verbose and silent can now be set per-project; the project-level value overrides the global value for that project's tests (#16133)
  • [@jest/fake-timers] Accept Temporal.Duration in jest.advanceTimersByTime() and jest.advanceTimersByTimeAsync() (#16128)
  • [@jest/fake-timers] Accept Temporal.Instant and Temporal.ZonedDateTime in jest.setSystemTime() and useFakeTimers({now}) (#16128)
  • [@jest/fake-timers] Support faking Temporal.Now.* (#16131)
  • [jest-mock] Add clearMocksOnScope(scope) on ModuleMocker for clearing every mock function exposed on a scope object (#16088)
  • [jest-resolve] Add canResolveSync() on Resolver so callers can detect when a user-configured resolver only exports an async hook (#16064)
  • [jest-runtime] Use synchronous evaluate() for ES modules without top-level await on Node versions that support it (v24.9+), and prefer the synchronous transform path when a sync transformer is configured (#16062)
  • [jest-runtime] Support require() of ES modules on Node v24.9+ (#16074)
  • [jest-runtime] Validate TC39 import attributes (with { type: 'json' }) on ESM imports (#16127)
  • [@jest/transform] Add canTransformSync(filename) on ScriptTransformer so callers can pick the sync vs async transform path (#16062)
  • [jest-util] Add isError helper (#16076)
  • [pretty-format] Support React 19 (#16123)

Fixes

  • [expect-utils] Fix toStrictEqual failing on structuredClone results due to cross-realm constructor mismatch (#15959)
  • [@jest/expect-utils] Prevent toMatchObject/subset matching from throwing when encountering exotic iterables (#15952)
  • [fake-timers] Convert Date to milliseconds before passing to @sinonjs/fake-timers (#16029)
  • [jest] Export GlobalConfig and ProjectConfig TypeScript types (#16132)
  • [jest-circus] Prevent crash when asyncError is undefined for non-Error throws (#16003)
  • [jest-circus, jest-jasmine2] Include Error.cause in JSON failureMessages output (#15967)
  • [jest-config] Fix preset path resolution on Windows when the preset uses subpath exports (#15961)
  • [jest-config] Allow collectCoverage and coverageProvider in project config without a validation warning (#16132)
  • [jest-config] Project config validator now emits "is not supported in an individual project configuration" instead of "probably a typing mistake" for known global-only options (#16132)
  • [jest-environment-node] Fix --localstorage-file warning on Node 25+ (#16086)
  • [jest-reporters] Apply global coverage threshold to unmatched pattern files in addition to glob/path thresholds (#16137)
  • [jest-reporters, jest-runner, jest-runtime, jest-transform] Fix coverage report not showing correct code coverage when using projects config option (#16140)
  • [jest-runtime] Resolve expect and @jest/expect from the internal module registry so test-file imports share the same JestAssertionError as the global expect (#16130)
  • [jest-runtime] Improve CJS-from-ESM interop: __esModule/Babel default unwrap, broader named-export coverage, and shared CJS singleton across importers (#16050)
  • [jest-runtime] Load .js files with ESM syntax but no "type":"module" marker as native ESM (#16050)
  • [jest-runtime] Extend the .js-with-ESM-syntax fallback to require() on Node v24.9+ - falls back to require(esm) when the CJS parser rejects ESM syntax (#16078)
  • [jest-runtime] Fix deadlocks and double-evaluation in concurrent ESM and wasm imports (#16050)
  • [jest-runtime] Fix error when require() is called after the Jest environment has been torn down (#15951)
  • [jest-runtime] Fix missing error when import() is called after the Jest environment has been torn down (#16080)
  • [jest-runtime] Fix virtual unstable_mockModule registrations not respected in ESM (#16081)
  • [jest-runtime] Apply moduleNameMapper when resolving modules with require.resolve() and the paths option (#16135)

Chore & Maintenance

  • [@jest/fake-timers] Upgrade @sinonjs/fake-timers (#16139)
  • [jest-runtime] Use synchronous linkRequests / instantiate for ESM linking on Node v24.9+ (#16063)

New Contributors

Full Changelog: v30.3.0...v30.4.0

30.3.0

Features

  • [jest-config] Add defineConfig and mergeConfig helpers for type-safe Jest config (#15844)
  • [jest-fake-timers] Add setTimerTickMode to configure how timers advance
  • [*] Reduce token usage when run through LLMs (3f17932)

Fixes

  • [jest-config] Keep CLI coverage output when using --json with --outputFile (#15918)
  • [jest-mock] Use Symbol from test environment (#15858)
  • [jest-reporters] Fix issue where console output not displayed for GHA reporter even with silent: false option (#15864)
  • [jest-runtime] Fix issue where user cannot utilize dynamic import despite specifying --experimental-vm-modules Node option (#15842)
  • [jest-test-sequencer] Fix issue where failed tests due to compilation errors not getting re-executed even with --onlyFailures CLI option (#15851)
  • [jest-util] Make sure process.features.require_module is false (#15867)

Chore & Maintenance

  • [*] Replace remaining micromatch uses with picomatch
  • [deps] Update to sinon/fake-timers v15
  • [docs] Update V30 migration guide to notify users on jest.mock() work with case-sensitive path (#15849)
  • Updated Twitter icon to match the latest brand guidelines (#15869)

30.2.0

Chore & Maintenance

  • [*] Update example repo for testing React Native projects (#15832)
  • [*] Update jest-watch-typeahead to v3 (#15830)

Features

  • [jest-environment-jsdom-abstract] Add support for JSDOM v27 (#15834)

Fixes

  • [babel-jest] Export the TransformerConfig interface (#15820)
  • [jest-config] Fix jest.config.ts with TS loader specified in docblock pragma (#15839)

30.1.0

Features

  • [jest-leak-detector] Configurable GC aggressiveness regarding to V8 heap snapshot generation (#15793)
  • [jest-runtime] Reduce redundant ReferenceError messages
  • [jest-core] Include test modules that failed to load when --onlyFailures is active

Fixes

  • `[jest-snapshot-utils] Fix deprecated goo.gl snapshot guide link not getting replaced with fully canonical URL (#15787)
  • [jest-circus] Fix it.concurrent not working with describe.skip (#15765)
  • [jest-snapshot] Fix mangled inline snapshot updates when used with Prettier 3 and CRLF line endings
  • [jest-runtime] Importing from @jest/globals in more than one file no longer breaks relative paths (#15772)

Chore

  • [expect] Update docblock for toContain() to display info on substring check (#15789)

30.0.5 (from changelog)

Features

  • [jest-config] Allow testMatch to take a string value
  • [jest-worker] Let workerIdleMemoryLimit accept 0 to always restart worker child processes

Fixes

  • [expect] Fix bigint error (#15702)

30.0.2

What's Changed

Fixes

  • [jest-matcher-utils] Make 'deepCyclicCopyObject' safer by setting descriptors to a null-prototype object (#15689)
  • [jest-util] Make garbage collection protection property writable (#15689)

Full Changelog: https://github.com/jestjs/jest/blob/main/CHANGELOG.md

30.0.1

What's Changed

Features

  • [jest-resolver] Implement the defaultAsyncResolver (#15679)

Fixes

  • [jest-resolver] Resolve builtin modules correctly (#15683)
  • [jest-environment-node, jest-util] Avoid setting globals cleanup protection symbol when feature is off (#15684)

Chore & Maintenance

  • [*] Remove and deprecate jest-repl package (#15673)
  • [jest-resolver] Replace custom isBuiltinModule with node's isBuiltin (#15685)

New Contributors

Full Changelog: https://github.com/jestjs/jest/blob/main/CHANGELOG.md

30.0.0

Today we are happy to announce the release of Jest 30. This release features a substantial number of changes, fixes, and improvements. While it is one of the largest major releases of Jest ever, we admit that three years for a major release is too long. In the future, we are aiming to make more frequent major releases to keep Jest great for the next decade.

If you want to skip all the news and just get going, run npm install jest@^30.0.0 and follow the migration guide: Upgrading from Jest 29 to 30.

Read the full blog post

Features

  • [*] Renamed globalsCleanupMode to globalsCleanup and --waitNextEventLoopTurnForUnhandledRejectionEvents to --waitForUnhandledRejections
  • [expect] Add ArrayOf asymmetric matcher for validating array elements. (#15567)
  • [babel-jest] Add option excludeJestPreset to allow opting out of babel-preset-jest (#15164)
  • [expect] Revert #15038 to fix expect(fn).toHaveBeenCalledWith(expect.objectContaining(...)) when there are multiple calls (#15508)
  • [jest-circus, jest-cli, jest-config] Add waitNextEventLoopTurnForUnhandledRejectionEvents flag to minimise performance impact of correct detection of unhandled promise rejections introduced in #14315 (#14681)
  • [jest-circus] Add a waitBeforeRetry option to jest.retryTimes (#14738)
  • [jest-circus] Add a retryImmediately option to jest.retryTimes (#14696)
  • [jest-circus, jest-jasmine2] Allow setupFilesAfterEnv to export an async function (#10962)
  • [jest-circus, jest-test-result] Add startedAt timestamp in TestCaseResultObject within onTestCaseResult (#15145)
  • [jest-cli] Export buildArgv (#15310)
  • [jest-config] [BREAKING] Add mts and cts to default moduleFileExtensions config (#14369)
  • [jest-config] [BREAKING] Update testMatch and testRegex default option for supporting mjs, cjs, mts, and cts (#14584)
  • [jest-config] Loads config file from provided path in package.json (#14044)
  • [jest-config] Allow loading jest.config.cts files (#14070)
  • [jest-config] Show rootDir in error message when a preset fails to load (#15194)
  • [jest-config] Support loading TS config files using esbuild-register via docblock loader (#15190)
  • [jest-config] Allow passing TS config loader options via docblock comment (#15234)
  • [jest-config] If Node is running with type stripping enabled, do not require a TS loader (#15480)
  • [@jest/core] Group together open handles with the same stack trace (#13417, & #14789)
  • [@jest/core] Add perfStats to surface test setup overhead (#14622)
  • [@jest/core] [BREAKING] Changed --filter to accept an object with shape { filtered: Array<string> } to match documentation (#13319)
  • [@jest/core] Support --outputFile option for --listTests (#14980)
  • [@jest/core] Stringify Errors properly with --json flag (#15329)
  • [@jest/core, @jest/test-sequencer] [BREAKING] Exposes globalConfig & contexts to TestSequencer (#14535, & #14543)
  • [jest-each] Introduce %$ option to add number of the test to its title (#14710)
  • [@jest/environment] [BREAKING] Remove deprecated jest.genMockFromModule() (#15042)
  • [@jest/environment] [BREAKING] Remove unnecessary defensive code (#15045)
  • [jest-environment-jsdom] [BREAKING] Upgrade JSDOM to v22 (#13825)
  • [@jest/environment-jsdom-abstract] Introduce new package which abstracts over the jsdom environment, allowing usage of custom versions of JSDOM (#14717)
  • [jest-environment-node] Update jest environment with dispose symbols Symbol (#14888 & #14909)
  • [expect, @jest/expect] [BREAKING] Add type inference for function parameters in CalledWith assertions (#15129)
  • [@jest/expect-utils] Properly compare all types of TypedArrays (#15178)
  • [@jest/fake-timers] [BREAKING] Upgrade @sinonjs/fake-timers to v13 (#14544 & #15470)
  • [@jest/fake-timers] Exposing new modern timers function advanceTimersToFrame() which advances all timers by the needed milliseconds to execute callbacks currently scheduled with requestAnimationFrame (#14598)
  • [jest-matcher-utils] Add SERIALIZABLE_PROPERTIES to allow custom serialization of objects (#14893)
  • [jest-mock] Add support for the Explicit Resource Management proposal to use the using keyword with jest.spyOn(object, methodName) (#14895)
  • [jest-reporters] Add support for DEC mode 2026 (#15008)
  • [jest-resolver] Support file:// URLs as paths (#15154)
  • [jest-resolve,jest-runtime,jest-resolve-dependencies] Pass the conditions when resolving stub modules (#15489)
  • [jest-runtime] Exposing new modern timers function jest.advanceTimersToFrame() from @jest/fake-timers (#14598)
  • [jest-runtime] Support import.meta.filename and import.meta.dirname (available from Node 20.11) (#14854)
  • [jest-runtime] Support import.meta.resolve (#14930)
  • [jest-runtime] [BREAKING] Make it mandatory to pass globalConfig to the Runtime constructor (#15044)
  • [jest-runtime] Add unstable_unmockModule (#15080)
  • [jest-runtime] Add onGenerateMock transformer callback for auto generated callbacks (#15433 & #15482)
  • [jest-runtime] [BREAKING] Use vm.compileFunction over vm.Script (#15461)
  • [@jest/schemas] Upgrade @sinclair/typebox to v0.34 (#15450)
  • [@jest/types] test.each(): Accept a readonly (as const) table properly (#14565)
  • [@jest/types] Improve argument type inference passed to test and describe callback functions from each tables (#14920)
  • [jest-snapshot] [BREAKING] Add support for Error causes in snapshots (#13965)
  • [jest-snapshot] Support Prettier 3 (#14566)
  • [@jest/util-snapshot] Extract utils used by tooling from jest-snapshot into its own package (#15095)
  • [pretty-format] [BREAKING] Do not render empty string children ('') in React plugin (#14470)

Fixes

  • [expect] Show AggregateError to display (#15346)
  • [*] Replace exit with exit-x (#15399)
  • [babel-plugin-jest-hoist] Use denylist instead of the deprecated blacklist for Babel 8 support (#14109)
  • [babel-plugin-jest-hoist] Do not rely on buggy Babel behaviour (#15415)
  • [expect] Check error instance type for toThrow/toThrowError (#14576)
  • [expect] Improve diff for failing expect.objectContaining (#15038)
  • [expect] Use Array.isArray to check if an array is an Array (#15101)
  • [expect] Fix Error cause assertion errors (#15339)
  • [jest-changed-files] Print underlying errors when VCS commands fail (#15052)
  • [jest-changed-files] Abort sl root call if output resembles a steam locomotive (#15053)
  • [jest-circus] [BREAKING] Prevent false test failures caused by promise rejections handled asynchronously (#14315)
  • [jest-circus] Replace recursive makeTestResults implementation with iterative one (#14760)
  • [jest-circus] Omit expect.hasAssertions() errors if a test already has errors (#14866)
  • [jest-circus, jest-expect, jest-snapshot] Pass test.failing tests when containing failing snapshot matchers (#14313)
  • [jest-circus] Concurrent tests now emit jest circus events at the correct point and in the expected order. (#15381)
  • [jest-cli] [BREAKING] Validate CLI flags that require arguments receives them (#14783)
  • [jest-config] Make sure to respect runInBand option (#14578)
  • [jest-config] Support testTimeout in project config (#14697)
  • [jest-config] Support coverageReporters in project config (#14697)
  • [jest-config] Allow reporters in project config (#14768)
  • [jest-config] Allow Node16/NodeNext/Bundler moduleResolution in project's tsconfig (#14739)
  • [@jest/create-cache-key-function] Correct the return type of createCacheKey (#15159)
  • [jest-each] Allow $keypath templates with null or undefined values (#14831)
  • [@jest/expect-utils] Fix comparison of DataView (#14408)
  • [@jest/expect-utils] [BREAKING] exclude non-enumerable in object matching (#14670)
  • [@jest/expect-utils] Fix comparison of URL (#14672)
  • [@jest/expect-utils] Check Symbol properties in equality (#14688)
  • [@jest/expect-utils] Catch circular references within arrays when matching objects (#14894)
  • [@jest/expect-utils] Fix not addressing to Sets and Maps as objects without keys (#14873)
  • [jest-haste-map] Fix errors or clobbering with multiple hasteImplModulePaths (#15522)
  • [jest-leak-detector] Make leak-detector more aggressive when running GC (#14526)
  • [jest-runtime] Properly handle re-exported native modules in ESM via CJS (#14589)
  • [jest-runtime] Refactor _importCoreModel so required core module is consistent if modified while loading (#15077)
  • [jest-schemas, jest-types] [BREAKING] Fix type of testFailureExitCode config option(#15232)
  • [jest-util] Make sure isInteractive works in a browser (#14552)
  • [pretty-format] [BREAKING] Print ArrayBuffer and DataView correctly (#14290)
  • [pretty-format] Fixed a bug where "anonymous custom elements" were not being printed as expected. (#15138)
  • [jest-cli] When specifying paths on the command line, only match against the relative paths of the test files (#12519)
    • [BREAKING] Changes testPathPattern configuration option to testPathPatterns, which now takes a list of patterns instead of the regex.
    • [BREAKING] --testPathPattern is now --testPathPatterns
    • [BREAKING] Specifying testPathPatterns when programmatically calling watch must be specified as new TestPathPatterns(patterns), where TestPathPatterns can be imported from @jest/pattern
  • [jest-reporters, jest-runner] Unhandled errors without stack get correctly logged to console (#14619)
  • [jest-util] Always load mjs files with import (#15447)
  • [jest-worker] Properly handle a circular reference error when worker tries to send an assertion fails where either the expected or actual value is circular (#15191)
  • [jest-worker] Properly handle a BigInt when worker tries to send an assertion fails where either the expected or actual value is BigInt (#15191)
  • [expect] Resolve issue where ObjectContaining matched non-object values. ([#15463])(#15463).
    • Adds a conditional/check to ensure the argument passed to expect is an object.
    • Add unit tests for new ObjectContaining behavior.
    • Remove invalid/wrong test case assertions for ObjectContaining.
  • [jest-worker] Addresses incorrect state on exit (#15610)

Performance

  • [*] [BREAKING] Bundle all of Jest's modules into index.js (#12348, #14550 & #14661)
  • [jest-haste-map] Only spawn one process to check for watchman installation (#14826)
  • [jest-runner] Better cleanup source-map-support after test to resolve (minor) memory leak (#15233)
  • [jest-circus, jest-environment-node, jest-repl, jest-runner, jest-util] Cleanup global variables on environment teardown to reduce memory leaks (#15215 & #15636 & #15643)

Chore & Maintenance

  • [jest-environment-jsdom, jest-environment-jsdom-abstract] Increased version of jsdom to ^26.0.0 (#15325CVE-2024-37890)
  • [*] Increase version of micromatch to ^4.0.7 (#15082)
  • [*] [BREAKING] Drop support for Node.js versions 14, 16, 19, 21 and 23 (#14460, #15118, #15623, #15640)
  • [*] [BREAKING] Drop support for typescript@4.3, minimum version is now 5.4 (#14542, #15621)
  • [*] Depend on exact versions of monorepo dependencies instead of ^ range (#14553)
  • [*] [BREAKING] Add ESM wrapper for all of Jest's modules (#14661)
  • [*] [BREAKING] Upgrade to glob@10 (#14509)
  • [*] Use TypeError over Error where appropriate (#14799)
  • [docs] Fix typos in CHANGELOG.md and packages/jest-validate/README.md (#14640)
  • [docs] Don't use alias matchers in docs (#14631)
  • [babel-jest, babel-preset-jest] [BREAKING] Increase peer dependency of @babel/core to ^7.11 (#14109)
  • [babel-jest, @jest/transform] Update babel-plugin-istanbul to v6 (#15156)
  • [babel-plugin-jest-hoist] Move unnecessary dependencies to devDependencies (#15010)
  • [expect] [BREAKING] Remove .toBeCalled(), .toBeCalledTimes(), .toBeCalledWith(), .lastCalledWith(), .nthCalledWith(), .toReturn(), .toReturnTimes(), .toReturnWith(), .lastReturnedWith(), .nthReturnedWith() and .toThrowError() matcher aliases (#14632)
  • [jest-cli, jest-config, @jest/types] [BREAKING] Remove deprecated --init argument (#14490)
  • [jest-config, @jest/core, jest-util] Upgrade ci-info (#14655)
  • [jest-mock] [BREAKING] Remove MockFunctionMetadataType, MockFunctionMetadata and SpyInstance types (#14621)
  • [@jest/reporters] Upgrade istanbul-lib-source-maps (#14924)
  • [jest-schemas] Upgrade @sinclair/typebox (#14775)
  • [jest-transform] Upgrade write-file-atomic (#14274)
  • [jest-util] Upgrade picomatch to v4 (#14653 & #14885)
  • [docs] Append to NODE_OPTIONS, not overwrite ([#14730](https://github.com/jestjs/jest/pull/14730))
  • [docs] Updated .toHaveBeenCalled() documentation to correctly reflect its functionality (#14842)
  • [docs] Link NestJS documentation on testing with Jest (#14940)
  • [docs] Revised documentation for .toHaveBeenCalled() to accurately depict its functionality. (#14853)
  • [docs] Removed ExpressJS reference link from documentation due to dead link (#15270)
  • [docs] Correct broken links in docs (#15359)

See the CHANGELOG.

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ jest-mock (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ jest-regex-util (indirect, 28.0.2 → 30.5.0) · Repo · Changelog

Release Notes

30.5.0

On a personal note: King Harald V of Norway passed away this morning. He ascended the throne 35 years ago, two months before I was born. This release is dedicated to his memory. Hvil i fred 🇳🇴


This is a big release. It touches jest-runtime, jest-resolve and jest-haste-map in many places, and with this many changes there might be regressions 😬. If your suite behaves differently after upgrading, please open an issue.

Highlights

whenCalledWith

Mock functions can now configure return values per argument list, contributed by @timkindberg (#16053):

const fn = jest.fn();
fn.whenCalledWith('apple').mockReturnValue('red');
fn.whenCalledWith('banana').mockReturnValue('yellow');
fn.whenCalledWith(expect.any(Number)).mockReturnValue('numeric');

fn('apple'); // 'red'
fn('banana'); // 'yellow'
fn(42); // 'numeric'
fn('grape'); // undefined

The returned object is a real Mock, so mockReturnValueOnce, mockResolvedValue, mockImplementation etc. all chain here too. Argument slots accept literals or any asymmetric matcher, with the same equality semantics as toHaveBeenCalledWith(). Calls that match nothing fall through to the base mock. See the Mock Functions docs for matching and precedence details.

Describe-level retries

jest.retryTimes() can now retry a whole describe block instead of a single test, contributed by @soltonigiri (#16322). Each attempt reruns the block's beforeAll/afterAll hooks, child tests and nested describes, which helps when tests in a block depend on shared state:

describe('workflow', () => {
  jest.retryTimes(3, {entireDescribe: true});

  test('first step', () => {});
  test('second step', () => {}); // a failure retries the entire block
});

New file watcher

The non-watchman path of jest-haste-map is rewritten. @parcel/watcher replaces the homegrown NodeWatcher and FSEventsWatcher (#16188), and fdir replaces the hand-rolled directory recursion in the crawler (#16187). A batch of fixes also makes watching and indexing survive locked files on Windows, watchman failures, and duplicate manual mocks (#16295, #16358, #16355, #16360).

If you can, please run your suite with --no-watchman (in and out of watch mode) to exercise the new crawler and watchers, and report anything odd 👍

Long-requested dependency updates

  • babel-plugin-istanbul is updated to v8 (#16049)
  • glob is updated to v13 (#16397)
  • source-map-support is replaced with an implementation in @jest/source-map (#16327). This fixes a memory leak where source-map-support's process-global caches pinned every finished test file's sandbox. Source maps also survive environment teardown, --testLocationInResults looks up the right column, and scheme-prefixed sources like webpack:/// are kept as-is.

Performance

  • Warm module resolution costs about a third of what it did, and repeated work is gone from the resolution hot path (#16373, #16371).
  • Per-require overhead in jest-runtime is cut: module ID resolution is skipped when no mock can apply, and core modules answer before the manual-mock probe (#16376).
  • jest-snapshot loads babel, semver and synckit lazily, so every test process loads ~200 fewer modules (#16387).
  • jest-haste-map caches the watchman socket path, so warm runs spawn no watchman processes (#16386), and reuses cached metadata for duplicated haste names instead of re-parsing them on every startup (#16351).

More new APIs

  • Snapshot failures expose the .snap file path as matcherResult.snapshotPath in failureDetails (#16374).
  • --collectTests expands test.each/describe.each cases and reports per-status counts plus a summary line that matches a real run (#16259).
  • AggregateError inner errors and nested cause chains render with code frames and per-level indentation, and are included in --json output, retryReasons and reporter annotations (#16316).

ESM

A long list of fixes brings jest-runtime's module system closer to Node's:

  • Automocking and manual __mocks__ files now apply to ESM on Node 24.9+. Static imports, dynamic import() and require() of an ESM file generate an automock from the real module's namespace instead of failing with "Attempting to import a mock without a factory" (#16391).
  • Many jest.unstable_mockModule gaps are closed: mocks apply when the mocked file is require()d directly, async factories run once and fail the import instead of crashing the worker 😅, and mocks made inside jest.isolateModules stay scoped to that block (#16389, #16365).
  • require(esm), CJS/ESM interop, import.meta, data: URIs and error ordering now match Node in dozens of edge cases. See the Fixes section for the full list (#16364 through #16391).
  • The module-sync export condition resolves, so packages that expose their ESM entry point for require() load the same file Node picks (#16336).

The intentional divergences from Node's module system are now documented on the ECMAScript Modules page (#16368).

Resolver

  • The default resolver honors Node's --preserve-symlinks / NODE_PRESERVE_SYMLINKS (#16260).
  • moduleNameMapper applies to both spellings of core module specifiers (fs and node:fs), and builtins that only exist prefixed (node:sqlite, node:test) resolve asynchronously (#16390, #16388).
  • A user resolver can be written as an ES module (#16332).

On top of the highlights there are ~60 fixes across jest-circus, jest-haste-map, jest-config, jest-mock and the transform cache keys. See the full changelog below 😀


Features

  • [@jest/expect-utils, jest-mock] Add mockFn.whenCalledWith(...args) for configuring return values per argument list, with first-class asymmetric-matcher support (#16053)
  • [@jest/expect-utils] Export AsymmetricMatcher and FunctionParameters types (previously private to expect) (#16053)
  • [jest-circus, jest-core, jest-jasmine2, jest-test-result, jest-types] --collectTests now expands test.each/describe.each cases and reports per-status counts (skipped/todo via the new wouldRun flag for selected tests) plus a summary line that match a real run, including under --testNamePattern and .only/fdescribe focus on both the circus and jasmine2 runners (#16259)
  • [jest-circus, jest-environment, jest-runtime, jest-types] Add describe-level retries via jest.retryTimes(..., {entireDescribe: true}) (#16322)
  • [jest-circus, jest-message-util, jest-reporters, jest-types] Add retryMessages to AssertionResult and export formatErrorStack, so the retry log renders nested cause and AggregateError sections with code frames instead of serialized [cause]:/[errors]: markers (#16316)
  • [jest-circus, jest-types] Add unhandledErrorsDetailed to Circus.RunResult, so an unhandled rejection reports its cause chain and AggregateError entries with code frames instead of a pre-serialized stack (#16316)
  • [jest-haste-map] Replace NodeWatcher and FSEventsWatcher with @parcel/watcher for the non-watchman watch path (#16188)
  • [jest-resolve] Bump unrs-resolver to 1.12.1, remove jest-pnp-resolver and unnecessary checks (#15721)
  • [jest-resolve] Honor Node's --preserve-symlinks / NODE_PRESERVE_SYMLINKS in the default resolver by passing symlinks: false to unrs-resolver (#16260)
  • [jest-runtime] Apply automocking and manual __mocks__ files to synchronously evaluable ESM graphs on Node 24.9+ - static imports, dynamic import() and require() of an ESM file now generate an automock from the real module's namespace instead of failing with "Attempting to import a mock without a factory". Graphs that need async evaluation (top-level await) or an async-only resolver or transformer still throw (#16391)
  • [jest-runtime] Route process.getBuiltinModule through the sandbox, so it returns the sandbox process and the hooked node:module instead of the host's (#16391)
  • [jest-runtime] Throw an actionable error from module.register() and module.registerHooks() inside a test - the hooks attached to the loader running Jest itself, never saw the sandboxed requires they were meant for, and stayed registered for every later test file in the worker (#16391)
  • [jest-runtime] Surface resolution and import-attribute errors in an ESM graph before executing any of its CJS dependencies on Node 24.9+, matching Node's run-nothing-on-a-broken-graph behavior; the legacy loader on older versions keeps its linking-time execution order (#16391)
  • [jest-runtime] Throw ERR_SOURCE_PHASE_NOT_DEFINED with an actionable message for import source and import.source(), instead of failing at instantiation with V8's bare "Source phase import object is not defined" (#16391)
  • [jest-runtime] Emit the JSON-without-import-attribute deprecation warning once per test file instead of once per worker, so it is no longer silently swallowed for every file after the first (#16391)
  • [jest-runtime] Set import.meta.main to true in the test file and false in every module it loads, matching Node 24+ (#16367)
  • [jest-runtime] Resolve the module-sync export condition, so a package that exposes its ESM entry point for require() loads the same file Node would (#16336)
  • [jest-snapshot] Add external snapshot paths to custom reporter failure details (#16374)

Fixes

  • [jest-console, jest-reporters] CustomConsole now buffers console output so TestResult.console is populated for reporters when verbose is enabled, while GitHubActionsReporter avoids replaying buffered output in verbose mode (#16155)
  • [expect, jest-message-util, jest-pattern, jest-regex-util, jest-util] Revert node: protocol imports to restore webpack/browser-bundle compatibility (#16167)
  • [expect] Widen toMatchObject and objectContaining parameter type from Record<string, unknown> to object so class instances are accepted (#16196)
  • [jest-circus] Call a generator test body with the shared test context, so this matches what a regular test function receives (#16347)
  • [jest-circus] Capture the error listeners of the parent process instead of the in-sandbox process, so listeners registered before the test file survive teardown and sandbox listeners no longer leak onto the parent (#16347)
  • [jest-circus] Clear currentlyRunningTest after skipped and todo tests (#16342)
  • [jest-circus] Prevent late done() callbacks from affecting later test or hook invocations (#16343)
  • [jest-circus, jest-jasmine2] Honor --expand when formatting node:assert failures, instead of always collapsing the diff (#16347)
  • [jest-circus, jest-jasmine2, jest-message-util] Serialize the inner errors of an AggregateError into failureMessages, retryReasons and unhandledErrors, so --json output and reporter annotations include them (#16316)
  • [jest-circus, jest-snapshot] Keep snapshot state and counts correct when a test retries (#16344)
  • [@jest/create-cache-key-function] Include the caller support flags in the generated key, so a transformer that emits ESM or CJS based on them no longer shares one cache entry between the two (#16331)
  • [@jest/create-cache-key-function] Include the stringified project config in the generated key, so editing a transformer's own settings invalidates what it cached (#16331)
  • [@jest/transform] Include the caller support flags in a transform's cache key, so a file transformed both as ESM and as CJS no longer serves one shape's output for the other (#16331)
  • [jest-config] Add missing findRelatedTests, outputFile, and replname entries to ValidConfig so they no longer trigger spurious "Unknown option" warnings (#16224)
  • [jest-config] Use --config for the global config when multiple --projects are specified (#16273)
  • [jest-core] Serialize bigint values in --json and --outputFile output as their literal form (4n), instead of failing the run with TypeError: Do not know how to serialize a BigInt (#16338)
  • [jest-core] Do not report a CustomGC async resource (used by N-API addons such as napi-rs for per-isolate GC bookkeeping) as an open handle, since it is napi_unref'd by the addon and can never keep the event loop alive (#16379)
  • [jest-each] Keep a $&, $`, $' or $$ inside a %p param value out of the replacement, so the title shows the value instead of the text around it (#16338)
  • [jest-each] Interpolate a bigint into a %j title as its literal form ("4n") at any depth, instead of throwing TypeError: Do not know how to serialize a BigInt while collecting the tests (#16338)
  • [jest-environment, jest-runtime] Bind sandboxInjectedGlobals to the right values when injectGlobals is false, instead of shifting every one of them by a position (#16377)
  • [jest-environment-node, jest-util] Only warn about a conflicting globalsCleanup mode when one was explicitly configured, and follow the mode that is actually in effect (#16323)
  • [jest-environment-node, jest-util] Stop resolving lazy globals when setting up an environment, so Node 26's builtin module globals are no longer loaded (and no longer emit their deprecation warnings) for every test file (#16324)
  • [jest-haste-map] Keep watch mode alive when an outside process briefly makes a file unreadable on Windows, instead of tearing the watcher down on EPERM (#16295)
  • [jest-haste-map] Keep indexing when an outside process holds a file open on Windows, instead of failing the whole crawl on EPERM (#16358)
  • [jest-haste-map] Keep a duplicated manual mock resolving when the file it pointed at is deleted in watch mode (#16360)
  • [jest-haste-map] Shut the worker farm down when a duplicate manual mock aborts the build under throwOnModuleCollision (#16354)
  • [jest-haste-map] Attach the watchman client's error listener before the first command, so a watchman failure falls back to the node crawler instead of crashing on an unhandled error event, and always end the client (#16355)
  • [jest-haste-map] Stop delivering watch events after WatchmanWatcher is closed, and route its warnings through the configured console (#16355)
  • [jest-haste-map] Restore the nested duplicates index correctly in ModuleMap.fromJSON, so a haste collision reported inside a test worker raises DuplicateHasteCandidatesError instead of a TypeError (#16353)
  • [jest-haste-map] Match watched files on a full extension, so moduleFileExtensions: ['js'] no longer accepts foo.mjs (#16352)
  • [jest-haste-map] Delimit the fields that make up the haste map cache key, so two different option sets cannot hash to the same cache file (#16352)
  • [jest-message-util] Print the inner errors of an AggregateError thrown inside a test (#16316)
  • [jest-message-util] Indent nested cause and AggregateError sections of a test failure by one level per depth, so the nesting is legible instead of rendering flat (#16316)
  • [jest-message-util] Color stack traces line by line so blank lines stay blank (#16316)
  • [jest-message-util] Detect Jest's own frames without assuming the checkout directory's name, and cover @jest/* packages, so stack traces and code frames point at user code (#16326)
  • [jest-mock] mockResolvedValue / mockRejectedValue now see all overload return types, so a Promise-returning overload survives even when a later overload returns a non-Promise (e.g. pg.Client['end']) (#16237)
  • [@jest-environment/jsdom-abstract] Make @types/jsdom a peer dependency (#16166)
  • [jest-mock] Remove the leftover own accessor descriptor when restoring a spyOn of an inherited getter or setter, so the instance keeps reflecting the prototype (#16226)
  • [jest-resolve] Include extensionsToTreatAsEsm in the shouldLoadAsEsm cache key, so projects with different extension lists don't read each other's answers (#16369)
  • [jest-resolve] Make getModuleIDAsync build and cache data: URI module IDs the same way as getModuleID (#16370)
  • [jest-resolve] Keep the node: prefix when resolving a core module asynchronously, so a builtin that only exists prefixed (node:sea, node:sqlite, node:test, node:test/reporters) resolves instead of failing as a missing bare package (#16388)
  • [jest-resolve] Look up manual mocks for node: protocol specifiers under the unprefixed name they are stored as (#16388)
  • [jest-resolve] Apply moduleNameMapper consistently to both spellings of core module specifiers (fs vs node:fs) (#16390)
  • [jest-resolve] Keep virtual and ordinary mock module IDs isolated across test files (#16296)
  • [jest-resolve] Guard missing require.resolve.paths (#16052)
  • [jest-resolve, jest-config, jest-runner] Support a user resolver written as an ES module (#16332)
  • [jest-resolve, jest-runtime] Throw the CJS parse error for ESM syntax in a "type": "commonjs" package or a .cjs file instead of loading it as ESM, matching Node (#16368)
  • [@jest/source-map] Keep source map sources that name a scheme, such as webpack:///, instead of resolving them into a path that does not exist (#16327)
  • [@jest/source-map] Look up --testLocationInResults positions at the right column, and keep a mapping to the first column instead of discarding it (#16327)
  • [@jest/source-map] Warn when a source map cannot be parsed, instead of silently leaving its frames untranslated (#16327)
  • [jest-runner, @jest/source-map] Keep a source-mapped stack for an error thrown after the test environment was torn down (#16327)
  • [jest-runtime, @jest/source-map] Keep source maps past teardown and past the next test file's install, so a stack from a file no earlier stack mentioned still points at the original source (#16330)
  • [jest-runtime] Report that no coverage was collected when getAllV8CoverageInfoCopy is called after teardown, instead of returning an empty result (#16385)
  • [jest-runtime] Cache a CJS module's parsed exports before walking its re-exports, so two modules that re-export each other no longer overflow the stack when imported from ESM (#16363)
  • [jest-runtime] Keep a re-exported ES module's parse failure from marking the re-exporting CommonJS file as ESM, so module.exports = require('./dep.mjs') loads instead of failing with module is not defined (#16363)
  • [jest-runtime] Scope module mocks instantiated inside jest.isolateModules/isolateModulesAsync to that block, so a mock first imported there no longer outlives it - matching how CommonJS mocks already behave (#16365)
  • [jest-runtime] Suspend module isolation while generating an automock, so loading the real module to read its shape no longer populates the isolated registry (#16365)
  • [jest-runtime] Check a cached ES module's status before require() returns it, so a module whose evaluation threw rethrows that error and one left linked by a failed sibling is evaluated instead of returning uninitialized bindings (#16364)
  • [jest-runtime] Report the original ERR_REQUIRE_ASYNC_MODULE when a require() of a top-level-await graph is retried, instead of a spurious "concurrent import()" error (#16364)
  • [jest-runtime] Throw the evaluation error when another caller's import() of the same module failed while we awaited it, instead of resolving with the errored module (#16364)
  • [jest-runtime] Mark the result of require()ing an ES module that has a default export with __esModule: true through a live-binding facade, and serve the same object from require.cache, matching Node (#16367)
  • [jest-runtime] Provide a CommonJS module's exports under the 'module.exports' named export when imported from ESM, matching Node 23+ (#16367)
  • [jest-runtime] Give the test file itself a non-null require.main (#16367)
  • [jest-runtime] Populate module.children with the modules a file loads, matching Node (#16368)
  • [jest-runtime] Provide import.meta.resolve and import.meta.jest in data: URI modules, accept any-case mediatype parameters, and use Node's error codes for invalid data: URIs (#16368)
  • [jest-runtime] Key ES modules by full URL, so query and fragment suffixes create the same module instances as Node and show up in import.meta.url (#16375)
  • [jest-runtime] Share modules between overlapping graphs when a CommonJS module require()s an ES module mid-load, instead of evaluating shared dependencies twice (#16375)
  • [jest-runtime] Throw ERR_REQUIRE_CYCLE_MODULE like Node when a CommonJS module require()s an ES module that is still being loaded, instead of evaluating the module a second time (#16366)
  • [jest-runtime] Key builtin modules in the ESM registry by one canonical specifier (#16341)
  • [jest-runtime] import.meta.resolve() for a builtin uses its node: specifier (#16341)
  • [jest-runtime] Fall back to native ESM when a .js file contains ESM syntax but has no "type":"module" marker (#16152)
  • [jest-runtime] Allow require() of ESM-marked files on Node < 24.9 via transform fallback (#16244)
  • [jest-runtime, @jest/transform] Surface actionable ERR_REQUIRE_ESM error for files with untransformed ESM syntax instead of the generic "unexpected token" message (#16244)
  • [jest-runtime] Support older test environments whose moduleMocker does not implement clearMocksOnScope (#16169)
  • [jest-runtime] Apply jest.unstable_mockModule when the mocked file itself is require()d, not only when it is imported as a dependency (#16389)
  • [jest-runtime] Apply jest.unstable_mockModule to statically imported data: URIs on Node 24.9+, matching dynamic import() (#16389)
  • [jest-runtime] Run an async jest.unstable_mockModule factory once per module instead of twice, and fail the import instead of crashing the worker when the factory rejects (#16389)
  • [jest-runtime] Hide a require(esm) module that failed to evaluate from require.cache, as Node does, instead of exposing a namespace with uninitialized bindings (#16389)
  • [jest-runtime] Strip the byte-order mark when importing a JSON module, matching require() and Node (#16389)
  • [jest-runtime] Throw ERR_REQUIRE_ASYNC_MODULE when require(esm) runs under an async-only custom resolver, instead of silently resolving with the default resolver (#16389)
  • [jest-runtime] Parse imported JSON modules with the test realm's JSON, so their objects pass instanceof Object inside the test like require()d JSON does (#16389)
  • [jest-runtime] Accept every file: URL string in the sandboxed module.createRequire, including one with a localhost authority, as Node does (#16389)
  • [jest-runtime] Point at {virtual: true} when jest.mock or jest.unstable_mockModule is given a module that cannot be resolved (#16389)
  • [jest-reporters] Fix coverage report table formatting in CI/GitHub Actions environments where process.stdout.columns is undefined by falling back to the COLUMNS env var or 80 columns in CI, preserving existing behaviour in other non-TTY environments (#16227)
  • [jest-runtime] Support CJS-in-ESM exports via "module.exports" named exports (#16277)
  • [jest-snapshot] Keep a skipped or failed test's hinted snapshots, instead of reporting them obsolete (#16348)
  • [jest-util] Stop globsToMatcher reusing a cached matcher compiled with different picomatch options, and keep its dot: true default when dot is passed as undefined (#16381)
  • [pretty-format] Move the react-is aliases into the @jest scope, so they cannot be shadowed by unrelated packages published under the alias names (#16333)

Chore & Maintenance

  • [docs] Document the intentional divergences from Node's module system in the ECMAScript Modules page (#16368)
  • [docs] Note deprecation of react-test-renderer in React Native tutorial and pretty-format README (#16294)
  • [docs] Use @testing-library/react-native in the React Native tutorial instead of the deprecated react-test-renderer (#16318)
  • [babel-jest, @jest/transform] Update babel-plugin-istanbul to v8 (#16049)
  • [jest-config, @jest/reporters, jest-runtime] Update glob to v13 (#16397)
  • [jest-haste-map] Refactor massive class into multiple files (#16180)
  • [jest-haste-map] Drop walker dependency; replace hand-rolled directory recursion in the JS crawler and watcher startup with fdir (#16187)
  • [jest-haste-map] Reuse cached metadata for files whose haste name is a known duplicate, instead of re-reading and re-parsing them on every startup (#16351)
  • [jest-haste-map] Cache the watchman socket path and replace the watchman --version probe with get-sockname, so warm runs spawn no watchman processes (#16386)
  • [jest-resolve] Store the per-directory package-type lookup in the cache it reads, so it actually memoizes (#16369)
  • [jest-resolve, jest-runtime] Cut repeated work on the resolution hot path: hoist the platform-extension list to construction, memoize isCoreModule and the options cache-key serialization, skip mapper preparation when no moduleNameMapper is configured, run each mapper regex once, and stop re-parsing NODE_OPTIONS on every default-resolver call (#16371)
  • [jest-resolve] Cut warm resolution cost to about a third: reuse one unrs-resolver factory per options shape instead of cloning per resolution, compose the factory cache key from per-array cached strings instead of serializing options, and stop constructing an Error for misses that findNodeModule swallows; add a __benchmarks__ suite for the default resolver (#16373)
  • [jest-runner, @jest/source-map] Replace source-map-support with an implementation in @jest/source-map (#16327)
  • [jest-snapshot] Load babel, semver and synckit lazily, so requiring the package (which every test process does through @jest/expect) no longer loads ~200 modules that only writing inline snapshots needs (#16387)
  • [jest-runtime] Reduce per-require overhead: skip module ID resolution when no mock can apply, answer core modules before probing for a manual mock, share one require.cache proxy across modules, and cache empty files (#16376)
  • [@jest/source-map] Deprecate getCallsite in favour of SourceMapSupport#getCallsite (#16327)
  • [jest-runtime] Avoid magical null value in ESM loader (#16160)

New Contributors

Full Changelog: v30.4.2...v30.5.0

30.4.0

Big release! 😀

Main feature is a rewrite of our custom runtime in preparation for stabilisation of native support of ESM. As part of that work require(esm) module is now supported on Node 24.9+ (still requires --experimental-vm-modules like before).

In addition we now support fake timers for the recently released Temporal API in Node v26.

React 19 is also supported properly in pretty-format, meaning snapshots of React components now work like they should.

Due to all the changes, there might be regressions that snuck in. Please report them!

Full list of changes below

Features

  • [babel-jest] Support collecting coverage from .mts, .cts (and other) files (#15994)
  • [jest-circus, jest-cli, jest-config, jest-core, jest-jasmine2, jest-types] Add --collect-tests flag to discover and list tests without executing them (#16006)
  • [jest-config, jest-runner, jest-worker] Add workerGracefulExitTimeout config option to control how long workers are given to exit before being force-killed (#15984)
  • [jest-config] Add support for jest.config.mts as a valid configuration file (#16005)
  • [jest-config, jest-core, jest-reporters, jest-runner] verbose and silent can now be set per-project; the project-level value overrides the global value for that project's tests (#16133)
  • [@jest/fake-timers] Accept Temporal.Duration in jest.advanceTimersByTime() and jest.advanceTimersByTimeAsync() (#16128)
  • [@jest/fake-timers] Accept Temporal.Instant and Temporal.ZonedDateTime in jest.setSystemTime() and useFakeTimers({now}) (#16128)
  • [@jest/fake-timers] Support faking Temporal.Now.* (#16131)
  • [jest-mock] Add clearMocksOnScope(scope) on ModuleMocker for clearing every mock function exposed on a scope object (#16088)
  • [jest-resolve] Add canResolveSync() on Resolver so callers can detect when a user-configured resolver only exports an async hook (#16064)
  • [jest-runtime] Use synchronous evaluate() for ES modules without top-level await on Node versions that support it (v24.9+), and prefer the synchronous transform path when a sync transformer is configured (#16062)
  • [jest-runtime] Support require() of ES modules on Node v24.9+ (#16074)
  • [jest-runtime] Validate TC39 import attributes (with { type: 'json' }) on ESM imports (#16127)
  • [@jest/transform] Add canTransformSync(filename) on ScriptTransformer so callers can pick the sync vs async transform path (#16062)
  • [jest-util] Add isError helper (#16076)
  • [pretty-format] Support React 19 (#16123)

Fixes

  • [expect-utils] Fix toStrictEqual failing on structuredClone results due to cross-realm constructor mismatch (#15959)
  • [@jest/expect-utils] Prevent toMatchObject/subset matching from throwing when encountering exotic iterables (#15952)
  • [fake-timers] Convert Date to milliseconds before passing to @sinonjs/fake-timers (#16029)
  • [jest] Export GlobalConfig and ProjectConfig TypeScript types (#16132)
  • [jest-circus] Prevent crash when asyncError is undefined for non-Error throws (#16003)
  • [jest-circus, jest-jasmine2] Include Error.cause in JSON failureMessages output (#15967)
  • [jest-config] Fix preset path resolution on Windows when the preset uses subpath exports (#15961)
  • [jest-config] Allow collectCoverage and coverageProvider in project config without a validation warning (#16132)
  • [jest-config] Project config validator now emits "is not supported in an individual project configuration" instead of "probably a typing mistake" for known global-only options (#16132)
  • [jest-environment-node] Fix --localstorage-file warning on Node 25+ (#16086)
  • [jest-reporters] Apply global coverage threshold to unmatched pattern files in addition to glob/path thresholds (#16137)
  • [jest-reporters, jest-runner, jest-runtime, jest-transform] Fix coverage report not showing correct code coverage when using projects config option (#16140)
  • [jest-runtime] Resolve expect and @jest/expect from the internal module registry so test-file imports share the same JestAssertionError as the global expect (#16130)
  • [jest-runtime] Improve CJS-from-ESM interop: __esModule/Babel default unwrap, broader named-export coverage, and shared CJS singleton across importers (#16050)
  • [jest-runtime] Load .js files with ESM syntax but no "type":"module" marker as native ESM (#16050)
  • [jest-runtime] Extend the .js-with-ESM-syntax fallback to require() on Node v24.9+ - falls back to require(esm) when the CJS parser rejects ESM syntax (#16078)
  • [jest-runtime] Fix deadlocks and double-evaluation in concurrent ESM and wasm imports (#16050)
  • [jest-runtime] Fix error when require() is called after the Jest environment has been torn down (#15951)
  • [jest-runtime] Fix missing error when import() is called after the Jest environment has been torn down (#16080)
  • [jest-runtime] Fix virtual unstable_mockModule registrations not respected in ESM (#16081)
  • [jest-runtime] Apply moduleNameMapper when resolving modules with require.resolve() and the paths option (#16135)

Chore & Maintenance

  • [@jest/fake-timers] Upgrade @sinonjs/fake-timers (#16139)
  • [jest-runtime] Use synchronous linkRequests / instantiate for ESM linking on Node v24.9+ (#16063)

New Contributors

Full Changelog: v30.3.0...v30.4.0

30.0.1

What's Changed

Features

  • [jest-resolver] Implement the defaultAsyncResolver (#15679)

Fixes

  • [jest-resolver] Resolve builtin modules correctly (#15683)
  • [jest-environment-node, jest-util] Avoid setting globals cleanup protection symbol when feature is off (#15684)

Chore & Maintenance

  • [*] Remove and deprecate jest-repl package (#15673)
  • [jest-resolver] Replace custom isBuiltinModule with node's isBuiltin (#15685)

New Contributors

Full Changelog: https://github.com/jestjs/jest/blob/main/CHANGELOG.md

30.0.0

Today we are happy to announce the release of Jest 30. This release features a substantial number of changes, fixes, and improvements. While it is one of the largest major releases of Jest ever, we admit that three years for a major release is too long. In the future, we are aiming to make more frequent major releases to keep Jest great for the next decade.

If you want to skip all the news and just get going, run npm install jest@^30.0.0 and follow the migration guide: Upgrading from Jest 29 to 30.

Read the full blog post

Features

  • [*] Renamed globalsCleanupMode to globalsCleanup and --waitNextEventLoopTurnForUnhandledRejectionEvents to --waitForUnhandledRejections
  • [expect] Add ArrayOf asymmetric matcher for validating array elements. (#15567)
  • [babel-jest] Add option excludeJestPreset to allow opting out of babel-preset-jest (#15164)
  • [expect] Revert #15038 to fix expect(fn).toHaveBeenCalledWith(expect.objectContaining(...)) when there are multiple calls (#15508)
  • [jest-circus, jest-cli, jest-config] Add waitNextEventLoopTurnForUnhandledRejectionEvents flag to minimise performance impact of correct detection of unhandled promise rejections introduced in #14315 (#14681)
  • [jest-circus] Add a waitBeforeRetry option to jest.retryTimes (#14738)
  • [jest-circus] Add a retryImmediately option to jest.retryTimes (#14696)
  • [jest-circus, jest-jasmine2] Allow setupFilesAfterEnv to export an async function (#10962)
  • [jest-circus, jest-test-result] Add startedAt timestamp in TestCaseResultObject within onTestCaseResult (#15145)
  • [jest-cli] Export buildArgv (#15310)
  • [jest-config] [BREAKING] Add mts and cts to default moduleFileExtensions config (#14369)
  • [jest-config] [BREAKING] Update testMatch and testRegex default option for supporting mjs, cjs, mts, and cts (#14584)
  • [jest-config] Loads config file from provided path in package.json (#14044)
  • [jest-config] Allow loading jest.config.cts files (#14070)
  • [jest-config] Show rootDir in error message when a preset fails to load (#15194)
  • [jest-config] Support loading TS config files using esbuild-register via docblock loader (#15190)
  • [jest-config] Allow passing TS config loader options via docblock comment (#15234)
  • [jest-config] If Node is running with type stripping enabled, do not require a TS loader (#15480)
  • [@jest/core] Group together open handles with the same stack trace (#13417, & #14789)
  • [@jest/core] Add perfStats to surface test setup overhead (#14622)
  • [@jest/core] [BREAKING] Changed --filter to accept an object with shape { filtered: Array<string> } to match documentation (#13319)
  • [@jest/core] Support --outputFile option for --listTests (#14980)
  • [@jest/core] Stringify Errors properly with --json flag (#15329)
  • [@jest/core, @jest/test-sequencer] [BREAKING] Exposes globalConfig & contexts to TestSequencer (#14535, & #14543)
  • [jest-each] Introduce %$ option to add number of the test to its title (#14710)
  • [@jest/environment] [BREAKING] Remove deprecated jest.genMockFromModule() (#15042)
  • [@jest/environment] [BREAKING] Remove unnecessary defensive code (#15045)
  • [jest-environment-jsdom] [BREAKING] Upgrade JSDOM to v22 (#13825)
  • [@jest/environment-jsdom-abstract] Introduce new package which abstracts over the jsdom environment, allowing usage of custom versions of JSDOM (#14717)
  • [jest-environment-node] Update jest environment with dispose symbols Symbol (#14888 & #14909)
  • [expect, @jest/expect] [BREAKING] Add type inference for function parameters in CalledWith assertions (#15129)
  • [@jest/expect-utils] Properly compare all types of TypedArrays (#15178)
  • [@jest/fake-timers] [BREAKING] Upgrade @sinonjs/fake-timers to v13 (#14544 & #15470)
  • [@jest/fake-timers] Exposing new modern timers function advanceTimersToFrame() which advances all timers by the needed milliseconds to execute callbacks currently scheduled with requestAnimationFrame (#14598)
  • [jest-matcher-utils] Add SERIALIZABLE_PROPERTIES to allow custom serialization of objects (#14893)
  • [jest-mock] Add support for the Explicit Resource Management proposal to use the using keyword with jest.spyOn(object, methodName) (#14895)
  • [jest-reporters] Add support for DEC mode 2026 (#15008)
  • [jest-resolver] Support file:// URLs as paths (#15154)
  • [jest-resolve,jest-runtime,jest-resolve-dependencies] Pass the conditions when resolving stub modules (#15489)
  • [jest-runtime] Exposing new modern timers function jest.advanceTimersToFrame() from @jest/fake-timers (#14598)
  • [jest-runtime] Support import.meta.filename and import.meta.dirname (available from Node 20.11) (#14854)
  • [jest-runtime] Support import.meta.resolve (#14930)
  • [jest-runtime] [BREAKING] Make it mandatory to pass globalConfig to the Runtime constructor (#15044)
  • [jest-runtime] Add unstable_unmockModule (#15080)
  • [jest-runtime] Add onGenerateMock transformer callback for auto generated callbacks (#15433 & #15482)
  • [jest-runtime] [BREAKING] Use vm.compileFunction over vm.Script (#15461)
  • [@jest/schemas] Upgrade @sinclair/typebox to v0.34 (#15450)
  • [@jest/types] test.each(): Accept a readonly (as const) table properly (#14565)
  • [@jest/types] Improve argument type inference passed to test and describe callback functions from each tables (#14920)
  • [jest-snapshot] [BREAKING] Add support for Error causes in snapshots (#13965)
  • [jest-snapshot] Support Prettier 3 (#14566)
  • [@jest/util-snapshot] Extract utils used by tooling from jest-snapshot into its own package (#15095)
  • [pretty-format] [BREAKING] Do not render empty string children ('') in React plugin (#14470)

Fixes

  • [expect] Show AggregateError to display (#15346)
  • [*] Replace exit with exit-x (#15399)
  • [babel-plugin-jest-hoist] Use denylist instead of the deprecated blacklist for Babel 8 support (#14109)
  • [babel-plugin-jest-hoist] Do not rely on buggy Babel behaviour (#15415)
  • [expect] Check error instance type for toThrow/toThrowError (#14576)
  • [expect] Improve diff for failing expect.objectContaining (#15038)
  • [expect] Use Array.isArray to check if an array is an Array (#15101)
  • [expect] Fix Error cause assertion errors (#15339)
  • [jest-changed-files] Print underlying errors when VCS commands fail (#15052)
  • [jest-changed-files] Abort sl root call if output resembles a steam locomotive (#15053)
  • [jest-circus] [BREAKING] Prevent false test failures caused by promise rejections handled asynchronously (#14315)
  • [jest-circus] Replace recursive makeTestResults implementation with iterative one (#14760)
  • [jest-circus] Omit expect.hasAssertions() errors if a test already has errors (#14866)
  • [jest-circus, jest-expect, jest-snapshot] Pass test.failing tests when containing failing snapshot matchers (#14313)
  • [jest-circus] Concurrent tests now emit jest circus events at the correct point and in the expected order. (#15381)
  • [jest-cli] [BREAKING] Validate CLI flags that require arguments receives them (#14783)
  • [jest-config] Make sure to respect runInBand option (#14578)
  • [jest-config] Support testTimeout in project config (#14697)
  • [jest-config] Support coverageReporters in project config (#14697)
  • [jest-config] Allow reporters in project config (#14768)
  • [jest-config] Allow Node16/NodeNext/Bundler moduleResolution in project's tsconfig (#14739)
  • [@jest/create-cache-key-function] Correct the return type of createCacheKey (#15159)
  • [jest-each] Allow $keypath templates with null or undefined values (#14831)
  • [@jest/expect-utils] Fix comparison of DataView (#14408)
  • [@jest/expect-utils] [BREAKING] exclude non-enumerable in object matching (#14670)
  • [@jest/expect-utils] Fix comparison of URL (#14672)
  • [@jest/expect-utils] Check Symbol properties in equality (#14688)
  • [@jest/expect-utils] Catch circular references within arrays when matching objects (#14894)
  • [@jest/expect-utils] Fix not addressing to Sets and Maps as objects without keys (#14873)
  • [jest-haste-map] Fix errors or clobbering with multiple hasteImplModulePaths (#15522)
  • [jest-leak-detector] Make leak-detector more aggressive when running GC (#14526)
  • [jest-runtime] Properly handle re-exported native modules in ESM via CJS (#14589)
  • [jest-runtime] Refactor _importCoreModel so required core module is consistent if modified while loading (#15077)
  • [jest-schemas, jest-types] [BREAKING] Fix type of testFailureExitCode config option(#15232)
  • [jest-util] Make sure isInteractive works in a browser (#14552)
  • [pretty-format] [BREAKING] Print ArrayBuffer and DataView correctly (#14290)
  • [pretty-format] Fixed a bug where "anonymous custom elements" were not being printed as expected. (#15138)
  • [jest-cli] When specifying paths on the command line, only match against the relative paths of the test files (#12519)
    • [BREAKING] Changes testPathPattern configuration option to testPathPatterns, which now takes a list of patterns instead of the regex.
    • [BREAKING] --testPathPattern is now --testPathPatterns
    • [BREAKING] Specifying testPathPatterns when programmatically calling watch must be specified as new TestPathPatterns(patterns), where TestPathPatterns can be imported from @jest/pattern
  • [jest-reporters, jest-runner] Unhandled errors without stack get correctly logged to console (#14619)
  • [jest-util] Always load mjs files with import (#15447)
  • [jest-worker] Properly handle a circular reference error when worker tries to send an assertion fails where either the expected or actual value is circular (#15191)
  • [jest-worker] Properly handle a BigInt when worker tries to send an assertion fails where either the expected or actual value is BigInt (#15191)
  • [expect] Resolve issue where ObjectContaining matched non-object values. ([#15463])(#15463).
    • Adds a conditional/check to ensure the argument passed to expect is an object.
    • Add unit tests for new ObjectContaining behavior.
    • Remove invalid/wrong test case assertions for ObjectContaining.
  • [jest-worker] Addresses incorrect state on exit (#15610)

Performance

  • [*] [BREAKING] Bundle all of Jest's modules into index.js (#12348, #14550 & #14661)
  • [jest-haste-map] Only spawn one process to check for watchman installation (#14826)
  • [jest-runner] Better cleanup source-map-support after test to resolve (minor) memory leak (#15233)
  • [jest-circus, jest-environment-node, jest-repl, jest-runner, jest-util] Cleanup global variables on environment teardown to reduce memory leaks (#15215 & #15636 & #15643)

Chore & Maintenance

  • [jest-environment-jsdom, jest-environment-jsdom-abstract] Increased version of jsdom to ^26.0.0 (#15325CVE-2024-37890)
  • [*] Increase version of micromatch to ^4.0.7 (#15082)
  • [*] [BREAKING] Drop support for Node.js versions 14, 16, 19, 21 and 23 (#14460, #15118, #15623, #15640)
  • [*] [BREAKING] Drop support for typescript@4.3, minimum version is now 5.4 (#14542, #15621)
  • [*] Depend on exact versions of monorepo dependencies instead of ^ range (#14553)
  • [*] [BREAKING] Add ESM wrapper for all of Jest's modules (#14661)
  • [*] [BREAKING] Upgrade to glob@10 (#14509)
  • [*] Use TypeError over Error where appropriate (#14799)
  • [docs] Fix typos in CHANGELOG.md and packages/jest-validate/README.md (#14640)
  • [docs] Don't use alias matchers in docs (#14631)
  • [babel-jest, babel-preset-jest] [BREAKING] Increase peer dependency of @babel/core to ^7.11 (#14109)
  • [babel-jest, @jest/transform] Update babel-plugin-istanbul to v6 (#15156)
  • [babel-plugin-jest-hoist] Move unnecessary dependencies to devDependencies (#15010)
  • [expect] [BREAKING] Remove .toBeCalled(), .toBeCalledTimes(), .toBeCalledWith(), .lastCalledWith(), .nthCalledWith(), .toReturn(), .toReturnTimes(), .toReturnWith(), .lastReturnedWith(), .nthReturnedWith() and .toThrowError() matcher aliases (#14632)
  • [jest-cli, jest-config, @jest/types] [BREAKING] Remove deprecated --init argument (#14490)
  • [jest-config, @jest/core, jest-util] Upgrade ci-info (#14655)
  • [jest-mock] [BREAKING] Remove MockFunctionMetadataType, MockFunctionMetadata and SpyInstance types (#14621)
  • [@jest/reporters] Upgrade istanbul-lib-source-maps (#14924)
  • [jest-schemas] Upgrade @sinclair/typebox (#14775)
  • [jest-transform] Upgrade write-file-atomic (#14274)
  • [jest-util] Upgrade picomatch to v4 (#14653 & #14885)
  • [docs] Append to NODE_OPTIONS, not overwrite ([#14730](https://github.com/jestjs/jest/pull/14730))
  • [docs] Updated .toHaveBeenCalled() documentation to correctly reflect its functionality (#14842)
  • [docs] Link NestJS documentation on testing with Jest (#14940)
  • [docs] Revised documentation for .toHaveBeenCalled() to accurately depict its functionality. (#14853)
  • [docs] Removed ExpressJS reference link from documentation due to dead link (#15270)
  • [docs] Correct broken links in docs (#15359)

See the CHANGELOG.

29.6.3

Fixes

  • [expect, @jest/expect-utils] ObjectContaining support symbol as key (#14414)
  • [expect] Remove @types/node from dependencies (#14385)
  • [jest-core] Use workers in watch mode by default to avoid crashes (#14059 & #14085).
  • [jest-reporters] Update istanbul-lib-instrument dependency to v6. (#14401)
  • [jest-mock] Revert #13692 as it was a breaking change (#14429)
  • [jest-mock] Revert #13866 as it was a breaking change (#14429)
  • [jest-mock] Revert #13867 as it was a breaking change (#14429)
  • [@jest/reporters] Marks Reporter's hooks as optional (#14433)
  • [jest-runtime] Fix dynamic ESM import module bug when loaded module through jest.isolateModulesAsync (#14397)

Chore & Maintenance

  • [jest-changed-files, jest-circus, jest-console, @jest/core, @jest/runtime, @jest/transform] Use invariant and notEmpty from jest-util rather than own internal (#14366)

New Contributors

Full Changelog: v29.6.2...v29.6.3

29.4.3

Features

  • [expect] Update toThrow() to be able to use error causes (#13606)
  • [jest-core] allow to use workerIdleMemoryLimit with only 1 worker or runInBand option (#13846)
  • [jest-message-util] Add support for error causes (#13868 & #13912)
  • [jest-runtime] Revert import assertions for JSON modules as it's been relegated to Stage 2 (#13911)

Fixes

  • [@jest/expect-utils] subsetEquality should consider also an object's inherited string keys (#13824)
  • [jest-mock] Clear mock state when jest.restoreAllMocks() is called (#13867)
  • [jest-mock] Prevent mockImplementationOnce and mockReturnValueOnce bleeding into withImplementation (#13888)
  • [jest-mock] Do not restore mocks when jest.resetAllMocks() is called (#13866)

New Contributors

Full Changelog: v29.4.2...v29.4.3

29.4.2

Features

Fixes

  • [expect, @jest/expect] Provide type of actual as a generic argument to Matchers to allow better-typed extensions (#13848)
  • [jest-circus] Added explicit mention of test failing because done() is not being called in error message (#13847)
  • [jest-runtime] Handle CJS re-exports of node core modules from ESM (#13856)
  • [jest-transform] Downgrade write-file-atomic to v4 (#13853)
  • [jest-worker] Ignore IPC messages not intended for Jest (#13543)

Chore & Maintenance

  • [*] make sure to exclude .eslintcache from published module (#13832)
  • [docs] Cleanup incorrect links in CHANGELOG.md (#13857)

New Contributors

Full Changelog: v29.4.1...v29.4.2

29.2.0

Features

  • [@jest/cli, jest-config] A seed for the test run will be randomly generated, or set by a CLI option (#13400)
  • [@jest/cli, jest-config] --show-seed will display the seed value in the report, and can be set via a CLI flag or through the config file (#13400)
  • [jest-config] Add readInitialConfig utility function (#13356)
  • [jest-core] Allow testResultsProcessor to be async (#13343)
  • [@jest/environment, jest-environment-node, jest-environment-jsdom, jest-runtime] Add getSeed() to the jest object (#13400)
  • [expect, @jest/expect-utils] Allow isA utility to take a type argument (#13355)
  • [expect] Expose AsyncExpectationResult and SyncExpectationResult types (#13411)

Fixes

  • [babel-plugin-jest-hoist] Ignore TSTypeQuery when checking for hoisted references (#13367)
  • [jest-core] Fix detectOpenHandles false positives for some special objects such as TLSWRAP (#13414)
  • [jest-mock] Fix mocking of getters and setters on classes (#13398)
  • [jest-reporters] Revert: Transform file paths into hyperlinks (#13399)
  • [@jest/types] Infer type of each table correctly when the table is a tuple or array (#13381)
  • [@jest/types] Rework typings to allow the *ReturnedWith matchers to be called with no argument (#13385)

Chore & Maintenance

  • [*] Update @babel/* deps, resulting in slightly different stack traces for each (#13422)

Performance

  • [jest-runner] Do not instrument v8 coverage data if coverage should not be collected (#13282)

New Contributors

Full Changelog: v29.1.2...v29.2.0

29.0.0

Blog post: https://jestjs.io/blog/2022/08/25/jest-29

Features

  • [expect] [BREAKING] Differentiate between MatcherContext MatcherUtils and MatcherState types (#13141)
  • [jest-circus] Add support for test.failing.each (#13142)
  • [jest-config] [BREAKING] Make snapshotFormat default to escapeString: false and printBasicPrototype: false (#13036)
  • [jest-config] [BREAKING] Remove undocumented collectCoverageOnlyFrom option (#13156)
  • [jest-environment-jsdom] [BREAKING] Upgrade to jsdom@20 (#13037, #13058)
  • [@jest/globals] Add jest.Mocked, jest.MockedClass, jest.MockedFunction and jest.MockedObject utility types (#12727)
  • [jest-mock] [BREAKING] Refactor Mocked* utility types. MaybeMockedDeep and MaybeMocked became Mocked and MockedShallow respectively; only deep mocked variants of MockedClass, MockedFunction and MockedObject are exported (#13123, #13124)
  • [jest-mock] [BREAKING] Change the default jest.mocked helper’s behavior to deep mocked (#13125)
  • [jest-snapshot] [BREAKING] Let babel find config when updating inline snapshots (#13150)
  • [@jest/test-result, @jest/types] [BREAKING] Replace Bytes and Milliseconds types with number (#13155)
  • [jest-worker] Adds workerIdleMemoryLimit option which is used as a check for worker memory leaks >= Node 16.11.0 and recycles child workers as required (#13056, #13105, #13106, #13107)
  • [pretty-format] [BREAKING] Remove ConvertAnsi plugin in favour of jest-serializer-ansi-escapes (#13040)
  • [pretty-format] Allow to opt out from sorting object keys with compareKeys: null (#12443)

Fixes

  • [jest-config] Fix testing multiple projects with TypeScript config files (#13099)
  • [@jest/expect-utils] Fix deep equality of ImmutableJS Record (#13055)
  • [jest-haste-map] Increase the maximum possible file size that jest-haste-map can handle (#13094)
  • [jest-runtime] Properly support CJS re-exports from dual packages (#13170)
  • [jest-snapshot] Make prettierPath optional in SnapshotState (#13149)
  • [jest-snapshot] Fix parsing error from inline snapshot files with JSX (#12760)
  • [jest-worker] When a process runs out of memory worker exits correctly and doesn't spin indefinitely (#13054)

Chore & Maintenance

  • [*] [BREAKING] Drop support for Node v12 and v17 (#13033)
  • [docs] Fix webpack name (#13049)
  • [docs] Explicit how to set n for --bail (#13128)
  • [docs] Update Enzyme URL (#13166)
  • [jest-leak-detector] Remove support for weak-napi (#13035)
  • [jest-snapshot] [BREAKING] Require rootDir as argument to SnapshotState (#13150)

New Contributors

Full Changelog: v28.1.3...v29.0.0

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ jest-resolve (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ jest-resolve-dependencies (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ jest-runner (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ jest-runtime (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ jest-snapshot (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ jest-util (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ jest-validate (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ jest-watcher (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ js-yaml (indirect, 3.14.1 → 3.15.2) · Repo · Changelog

Commits

See the full diff on Github. The new version differs by 15 commits:

↗️ jsesc (indirect, 2.5.2 → 3.1.0) · Repo

Commits

See the full diff on Github. The new version differs by 18 commits:

↗️ make-dir (indirect, 3.1.0 → 4.0.0) · Repo

Release Notes

4.0.0

Breaking

Improvements

v3.1.0...v4.0.0

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 10 commits:

↗️ node-releases (indirect, 2.0.2 → 2.0.54) · Repo

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ picocolors (indirect, 1.0.0 → 1.1.1) · Repo · Changelog

Release Notes

1.1.1

What's new?

  • Moved TypeScript declarations to a d.ts file #82
  • Reworked color detection algorithm to properly work with empty strings in NO_COLOR and FORCE_COLOR env variables #87
  • Eliminated require() call to make the package compatible with some tools #87

1.1.0

What's new?

  • Added bright color variants #55

1.0.1

What's new?

  • Updated color detection mechanism to work properly on Vercel Edge Runtime #64
  • Remove use of recursion to avoid possible stack overflow for very long inputs #56

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 16 commits:

↗️ pirates (indirect, 4.0.5 → 4.0.7) · Repo

Release Notes

4.0.7

4.0.7 (2025-03-27)

Bug Fixes

  • remove build process and ship source directly (924ccc3)
  • Update some wording and fix grammar in messages (#121) (f39d729)

4.0.6

4.0.6 (2023-06-20)

Bug Fixes

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 48 commits:

↗️ pretty-format (indirect, 28.1.3 → 30.5.0) · Repo · Changelog

Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ semver (indirect, 6.3.0 → 6.3.1) · Repo · Changelog

Security Advisories 🚨

🚨 semver vulnerable to Regular Expression Denial of Service

Versions of the package semver before 7.5.2 on the 7.x branch, before 6.3.1 on the 6.x branch, and all other versions before 5.7.2 are vulnerable to Regular Expression Denial of Service (ReDoS) via the function new Range, when untrusted user data is provided as a range.

Release Notes

6.3.1

6.3.1 (2023-07-10)

Bug Fixes

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 3 commits:

↗️ stack-utils (indirect, 2.0.5 → 2.0.6) · Repo

Commits

See the full diff on Github. The new version differs by 11 commits:

↗️ test-exclude (indirect, 6.0.0 → 7.0.2) · Repo · Changelog

Release Notes

7.0.2 (from changelog)

Bug Fixes

7.0.1 (from changelog)

Bug Fixes

  • add windowsPathsNoEscape to preserve behaviour on Windows (15dcfaa)

7.0.0 (from changelog)

⚠ BREAKING CHANGES

  • deps: Node 18 is now the minimum required version.

Bug Fixes

  • deps: update deps making Node 18 minimum (#56) (ad7dfe1)

Does any of this look wrong? Please let us know.

↗️ v8-to-istanbul (indirect, 9.0.1 → 9.3.0) · Repo · Changelog

Release Notes

9.3.0

9.3.0 (2024-06-22)

Features

9.2.0

9.2.0 (2023-11-22)

Features

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 26 commits:

↗️ write-file-atomic (indirect, 4.0.1 → 5.0.1) · Repo · Changelog

Release Notes

5.0.1

5.0.1 (2023-04-26)

Dependencies

5.0.0

5.0.0 (2022-10-10)

⚠️ BREAKING CHANGES

  • write-file-atomic is now compatible with the following semver range for node: ^14.17.0 || ^16.13.0 || >=18.0.0

Features

4.0.2

4.0.2 (2022-08-16)

Bug Fixes

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 42 commits:

↗️ yargs (indirect, 17.5.1 → 17.7.3) · Repo · Changelog

Commits

See the full diff on Github. The new version differs by 32 commits:

🆕 @​babel/helper-globals (added, 7.29.7)

🆕 @​babel/helper-string-parser (added, 7.29.7)

🆕 @​babel/plugin-syntax-class-static-block (added, 7.14.5)

🆕 @​babel/plugin-syntax-import-attributes (added, 7.29.7)

🆕 @​babel/plugin-syntax-jsx (added, 7.29.7)

🆕 @​babel/plugin-syntax-private-property-in-object (added, 7.14.5)

🆕 @​emnapi/core (added, 1.10.0)

🆕 @​emnapi/runtime (added, 1.10.0)

🆕 @​emnapi/wasi-threads (added, 1.2.1)

🆕 @​isaacs/cliui (added, 8.0.2)

🆕 @​jest/diff-sequences (added, 30.5.0)

🆕 @​jest/get-type (added, 30.5.0)

🆕 @​jest/pattern (added, 30.5.0)

🆕 @​jest/react-is-18 (added, npm:react-is@18.3.1)

🆕 @​jest/react-is-19 (added, npm:react-is@19.2.8)

🆕 @​jest/snapshot-utils (added, 30.5.0)

🆕 @​jridgewell/remapping (added, 2.3.5)

🆕 @​napi-rs/wasm-runtime (added, 1.2.3)

🆕 @​parcel/watcher (added, 2.6.0)

🆕 @​parcel/watcher-android-arm64 (added, 2.6.0)

🆕 @​parcel/watcher-darwin-arm64 (added, 2.6.0)

🆕 @​parcel/watcher-darwin-x64 (added, 2.6.0)

🆕 @​parcel/watcher-freebsd-x64 (added, 2.6.0)

🆕 @​parcel/watcher-linux-arm-glibc (added, 2.6.0)

🆕 @​parcel/watcher-linux-arm-musl (added, 2.6.0)

🆕 @​parcel/watcher-linux-arm64-glibc (added, 2.6.0)

🆕 @​parcel/watcher-linux-arm64-musl (added, 2.6.0)

🆕 @​parcel/watcher-linux-x64-glibc (added, 2.6.0)

🆕 @​parcel/watcher-linux-x64-musl (added, 2.6.0)

🆕 @​parcel/watcher-win32-arm64 (added, 2.6.0)

🆕 @​parcel/watcher-win32-x64 (added, 2.6.0)

🆕 @​pkgjs/parseargs (added, 0.11.0)

🆕 @​pkgr/core (added, 0.3.6)

🆕 @​tybys/wasm-util (added, 0.10.3)

🆕 @​ungap/structured-clone (added, 1.4.0)

🆕 @​unrs/resolver-binding-android-arm-eabi (added, 1.12.2)

🆕 @​unrs/resolver-binding-android-arm64 (added, 1.12.2)

🆕 @​unrs/resolver-binding-darwin-arm64 (added, 1.12.2)

🆕 @​unrs/resolver-binding-darwin-x64 (added, 1.12.2)

🆕 @​unrs/resolver-binding-freebsd-x64 (added, 1.12.2)

🆕 @​unrs/resolver-binding-linux-arm-gnueabihf (added, 1.12.2)

🆕 @​unrs/resolver-binding-linux-arm-musleabihf (added, 1.12.2)

🆕 @​unrs/resolver-binding-linux-arm64-gnu (added, 1.12.2)

🆕 @​unrs/resolver-binding-linux-arm64-musl (added, 1.12.2)

🆕 @​unrs/resolver-binding-linux-loong64-gnu (added, 1.12.2)

🆕 @​unrs/resolver-binding-linux-loong64-musl (added, 1.12.2)

🆕 @​unrs/resolver-binding-linux-ppc64-gnu (added, 1.12.2)

🆕 @​unrs/resolver-binding-linux-riscv64-gnu (added, 1.12.2)

🆕 @​unrs/resolver-binding-linux-riscv64-musl (added, 1.12.2)

🆕 @​unrs/resolver-binding-linux-s390x-gnu (added, 1.12.2)

🆕 @​unrs/resolver-binding-linux-x64-gnu (added, 1.12.2)

🆕 @​unrs/resolver-binding-linux-x64-musl (added, 1.12.2)

🆕 @​unrs/resolver-binding-openharmony-arm64 (added, 1.12.2)

🆕 @​unrs/resolver-binding-wasm32-wasi (added, 1.12.2)

🆕 @​unrs/resolver-binding-win32-arm64-msvc (added, 1.12.2)

🆕 @​unrs/resolver-binding-win32-ia32-msvc (added, 1.12.2)

🆕 @​unrs/resolver-binding-win32-x64-msvc (added, 1.12.2)

🆕 baseline-browser-mapping (added, 2.11.20)

🆕 eastasianwidth (added, 0.2.0)

🆕 exit-x (added, 0.2.2)

🆕 foreground-child (added, 3.3.1)

🆕 jackspeak (added, 3.4.3)

🆕 napi-postinstall (added, 0.3.4)

🆕 node-addon-api (added, 7.1.1)

🆕 package-json-from-dist (added, 1.0.1)

🆕 path-scurry (added, 2.0.2)

🆕 pure-rand (added, 7.0.1)

🆕 string-width-cjs (added, npm:string-width@4.2.3)

🆕 strip-ansi-cjs (added, npm:strip-ansi@6.0.1)

🆕 synckit (added, 0.11.13)

🆕 tslib (added, 2.8.1)

🆕 unrs-resolver (added, 1.12.2)

🆕 update-browserslist-db (added, 1.3.2)

🆕 wrap-ansi-cjs (added, npm:wrap-ansi@7.0.0)

🗑️ @​ampproject/remapping (removed)

🗑️ @​babel/helper-environment-visitor (removed)

🗑️ @​babel/helper-function-name (removed)

🗑️ @​babel/helper-hoist-variables (removed)

🗑️ @​babel/helper-simple-access (removed)

🗑️ @​babel/helper-split-export-declaration (removed)

🗑️ @​babel/highlight (removed)

🗑️ @​jridgewell/set-array (removed)

🗑️ @​types/graceful-fs (removed)

🗑️ @​types/prettier (removed)

🗑️ diff-sequences (removed)

🗑️ exit (removed)

🗑️ globals (removed)

🗑️ jest-get-type (removed)

🗑️ jest-pnp-resolver (removed)

🗑️ kleur (removed)

🗑️ makeerror (removed)

🗑️ micromatch (removed)

🗑️ prompts (removed)

🗑️ react-is (removed)

🗑️ resolve.exports (removed)

🗑️ sisteransi (removed)

🗑️ tmpl (removed)

🗑️ to-fast-properties (removed)

🗑️ walker (removed)