v30.4.0
📦 jestView on GitHub →
✨ 16 features🐛 21 fixes🔧 36 symbols
Summary
This major release rewrites the custom runtime to better support native ESM, enabling `require(esm)` on Node 24.9+ and adding support for the Temporal API. It also includes proper snapshot support for React 19 and numerous fixes across core modules.
Migration Steps
- If you rely on synchronous evaluation of ES Modules without top-level await, ensure you are running Node v24.9+ to benefit from the synchronous path.
- If you use custom resolvers, consider implementing canResolveSync() if you need synchronous resolution checks.
✨ New Features
- Support collecting coverage from .mts, .cts (and other) files in babel-jest.
- Add --collect-tests flag to discover and list tests without executing them.
- Add workerGracefulExitTimeout config option to control how long workers are given to exit before being force-killed.
- Add support for jest.config.mts as a valid configuration file.
- verbose and silent can now be set per-project; the project-level value overrides the global value for that project's tests.
- Accept Temporal.Duration in jest.advanceTimersByTime() and jest.advanceTimersByTimeAsync().
- Accept Temporal.Instant and Temporal.ZonedDateTime in jest.setSystemTime() and useFakeTimers({now}).
- Support faking Temporal.Now.* in fake timers.
- Add clearMocksOnScope(scope) on ModuleMocker for clearing every mock function exposed on a scope object.
- Add canResolveSync() on Resolver so callers can detect when a user-configured resolver only exports an async hook.
- 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.
- Support require() of ES modules on Node v24.9+.
- Validate TC39 import attributes (with { type: 'json' }) on ESM imports.
- Add canTransformSync(filename) on ScriptTransformer so callers can pick the sync vs async transform path.
- Add isError helper in jest-util.
- Support React 19 in pretty-format.
🐛 Bug Fixes
- Fix toStrictEqual failing on structuredClone results due to cross-realm constructor mismatch.
- Prevent toMatchObject/subset matching from throwing when encountering exotic iterables.
- Convert Date to milliseconds before passing to @sinonjs/fake-timers.
- Export GlobalConfig and ProjectConfig TypeScript types.
- Prevent crash when asyncError is undefined for non-Error throws in jest-circus.
- Include Error.cause in JSON failureMessages output for jest-circus and jest-jasmine2.
- Fix preset path resolution on Windows when the preset uses subpath exports.
- Allow collectCoverage and coverageProvider in project config without a validation warning.
- Project config validator now emits "is not supported in an individual project configuration" instead of "probably a typing mistake" for known global-only options.
- Fix --localstorage-file warning on Node 25+.
- Apply global coverage threshold to unmatched pattern files in addition to glob/path thresholds.
- Fix coverage report not showing correct code coverage when using projects config option.
- Resolve expect and @jest/expect from the internal module registry so test-file imports share the same JestAssertionError as the global expect.
- Improve CJS-from-ESM interop: __esModule/Babel default unwrap, broader named-export coverage, and shared CJS singleton across importers.
- Load .js files with ESM syntax but no "type":"module" marker as native ESM.
- 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.
- Fix deadlocks and double-evaluation in concurrent ESM and wasm imports.
- Fix error when require() is called after the Jest environment has been torn down.
- Fix missing error when import() is called after the Jest environment has been torn down.
- Fix virtual unstable_mockModule registrations not respected in ESM.
- Apply moduleNameMapper when resolving modules with require.resolve() and the paths option.
Affected Symbols
babel-jestjest-circusjest-clijest-configjest-corejest-jasmine2jest-typesTemporal.DurationTemporal.InstantTemporal.ZonedDateTimeTemporal.Now.*ModuleMockerResolverjest-resolvejest-runtimeScriptTransformerjest-utilpretty-formatexpect-utilstoMatchObjectstructuredClone@jest/fake-timersDate@sinonjs/fake-timersGlobalConfigProjectConfigError.causejest-environment-nodejest-reportersjest-runnerjest-transformexpect@jest/expectJestAssertionErrorrequire.resolve()paths