npm / jest
jest
What changed in jest 30, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-17.
6 breaking1 security6 deprecations26 new APIs and options6 performance22 behavior and defaults2 tooling44 fixes and other
See which of these apply to your code, ranked, in your agent:
npx @unstale/cli initjest 30113 changes
Breaking changes 6
Module mocks instantiated inside an isolated block are now scoped to that block instead of outliving it.
Calls to
module.register()andmodule.registerHooks()inside a test now throw an actionable error because their hooks cannot affect sandboxed requires.Watched files now match full extensions, so
moduleFileExtensions: ['js']no longer acceptsfoo.mjs.ESM requiring, CJS/ESM interop and related error behavior are brought closer to Node, including live-binding facades and Node-compatible errors for cycles and top-level await.
When importing CJS from ESM, module.exports is always the ESM default; __esModule unwrapping is no longer applied, aligning behavior with Node.
The global coverage threshold now applies to unmatched pattern files in addition to glob and path thresholds.
Security 1
The aliases are moved into the @jest scope so unrelated packages published under the alias names cannot shadow them.
Deprecations 6
A project config containing this global-only option now warns instead of silently ignoring it.
A project config containing this option now warns instead of dropping it without notice.
A project config containing this global-only option now warns instead of silently ignoring it.
A project config containing this global-only option now warns instead of silently ignoring it.
A project config containing this global-only option now warns instead of silently ignoring it.
getCallsite is deprecated in favor of SourceMapSupport#getCallsite.
New APIs and options 26
The
@jest/expect-utilspackage now exports theAsymmetricMatchertype, which was previously private toexpect.CommonJS exports are available under the
module.exportsnamed export when imported from ESM, matching Node 23+.The
@jest/expect-utilspackage now exports theFunctionParameterstype, which was previously private toexpect.Snapshot failure details expose the path to the external
.snapfile for custom reporters.Assertion results now include retry messages, with nested causes and AggregateError sections rendered with code frames.
Set
entireDescribe: trueto retry a whole describe block, rerunning its hooks, child tests and nested describes on each attempt.Circus run results now include detailed unhandled errors, including cause chains and AggregateError entries with code frames.
Mock functions can configure chained mock behavior for specific argument lists, including asymmetric matchers; unmatched calls fall through to the base mock.
Selected tests in
--collectTestsoutput have a new flag indicating whether they would run.Custom runner configuration options can be specified using the tuple format ['runner-path', {options}].
Resolver callers can detect when a user-configured resolver only exports an async hook.
ScriptTransformer callers can choose the synchronous or asynchronous transform path.
ModuleMocker can clear every mock function exposed on a scope object.
Discover and list tests without executing them.
Exports the GlobalConfig TypeScript type.
Adds an error-checking helper to jest-util.
Accepts Temporal.Duration values.
Accepts Temporal.Duration values.
Use jest.config.mts as a valid Jest configuration file.
Exports the ProjectConfig TypeScript type.
Set silent per project; the project-level value overrides the global value for that project's tests.
Set verbose per project; the project-level value overrides the global value for that project's tests.
Control how long workers are given to exit before being force-killed.
Adds a helper for type-safe Jest configuration.
Adds a helper for type-safe Jest configuration.
Adds a method to configure how timers advance.
Performance 6
Warm resolution cost is cut by reusing resolver factories and cached strings, and by avoiding Error construction for swallowed misses.
babel, semver, and synckit are loaded lazily, avoiding loading about 200 modules when requiring the package unless writing inline snapshots needs them.
Cached metadata is reused for files whose haste name is a known duplicate, avoiding repeated reads and parsing on startup.
Repeated work on the resolution hot path is reduced through memoization and skipped preparation when no moduleNameMapper is configured.
Per-require overhead is reduced by skipping unnecessary module ID resolution and manual-mock probes, sharing a require.cache proxy, and caching empty files.
The watchman socket path is cached and the version probe is replaced with get-sockname, so warm runs spawn no watchman processes.
Behavior and default changes 22
When no transformer claims a .ts, .mts or .cts file, Jest strips its TypeScript types with Node.
A project config containing this global-only option now warns instead of silently ignoring it.
A project config containing this option now warns instead of dropping it without notice.
Inner errors and nested causes render with code frames and indentation, and are included in JSON output, retry reasons and reporter annotations.
Collection expands
test.eachanddescribe.eachcases, reports per-status counts and a summary line, and accounts for selected tests that would run.When multiple
--projectsare specified,--configis now used for the global config.On Node 24.9+, automocking and manual
__mocks__files apply to synchronously evaluable ESM graphs, including static imports, dynamic imports andrequire().Jest sets
import.meta.mainto true in the test file and false in modules it loads, matching Node 24+.The default resolver now honors Node's
--preserve-symlinksoption andNODE_PRESERVE_SYMLINKSenvironment variable.The parameter type now accepts
objectrather than onlyRecord<string, unknown>, allowing class instances.The parameter type now accepts
objectrather than onlyRecord<string, unknown>, allowing class instances.A custom resolver can now be written as an ES module.
Improves interop with __esModule/Babel default unwrapping, broader named-export coverage, and a shared CJS singleton across importers.
JSON failureMessages output now includes Error.cause.
Jest validates TC39 import attributes on ESM imports.
Accepts Temporal.Instant and Temporal.ZonedDateTime values.
Loads .js files with ESM syntax as native ESM even without a type:module marker.
Known global-only options now receive the message “is not supported in an individual project configuration” instead of “probably a typing mistake.”
Supports requiring ES modules on Node v24.9+.
On Node v24.9+, the .js-with-ESM-syntax fallback uses require(esm) when the CJS parser rejects ESM syntax.
On Node versions that support it, ES modules without top-level await use synchronous evaluate(); Jest prefers the synchronous transform path when a sync transformer is configured.
The now option accepts Temporal.Instant and Temporal.ZonedDateTime values.
Tooling 2
babel-jest can collect coverage from .mts files.
Fake timers can now fake Temporal.Now.*.
Fixes and other changes 44
The command reports the released version instead of the previous version.
Absolute Windows paths in sources and sourceRoot resolve as absolute paths instead of being appended to the transformed file's directory.
Cache keys report the released version instead of the previous version.
Table row keys are escaped before building the interpolation RegExp, so special characters in column names no longer cause errors or match incorrectly.
The config that supplies the global config no longer warns about global-only options.
Patterns are matched against the module specifier as written again.
Package imports specifiers such as #dep resolve under ESM again.
ES modules are keyed by full URL, so query and fragment suffixes create distinct module instances and appear in
import.meta.url, matching Node.The option is now honored when formatting
node:assertfailures instead of always collapsing the diff.This config entry is now recognized by
ValidConfigand no longer triggers a spurious unknown-option warning.When given an unresolvable module with
{virtual: true}, the error now points at the virtual option.JSON output now serializes bigint values in literal form, such as
4n, instead of failing the run.Return-type inference now considers all overloads, preserving Promise-returning overloads even when a later overload returns a non-Promise.
Return-type inference now considers all overloads, preserving Promise-returning overloads even when a later overload returns a non-Promise.
The resolver now handles the
module-syncexport condition so packages can resolve the same ESM entry point forrequire()as Node.Jest now populates
module.childrenwith the modules a file loads, matching Node.Mappings now apply consistently to both bare and
node:-prefixed spellings of core module specifiers.This config entry is now recognized by
ValidConfigand no longer triggers a spurious unknown-option warning.This config entry is now recognized by
ValidConfigand no longer triggers a spurious unknown-option warning.The test file itself now has a non-null
require.main.Injected globals are now bound to the correct values when
injectGlobalsis false.Generator test bodies now receive the shared test context, so
thisbehaves as it does in a regular test function.Mocks apply when the mocked file is directly required, async factories run once and rejected factories fail the import instead of crashing the worker, and mocks remain scoped to isolated modules.
Fixes named imports from CJS modules whose module.exports is a function with own-property exports.
Prevents jest-circus from crashing when asyncError is undefined for non-Error throws.
Project configurations can set collectCoverage without a validation warning.
Fixes deadlocks and double-evaluation during concurrent ESM and wasm imports.
Project configurations can set coverageProvider without a validation warning.
Fake timers convert Date values to milliseconds before passing them to @sinonjs/fake-timers.
Test-file imports resolve expect and @jest/expect from the internal module registry so they share the global expect's JestAssertionError.
Restores the missing error when import() is called after the Jest environment has been torn down.
Fixes the warning on Node 25+.
Applied when resolving modules with require.resolve() and the paths option.
Fixes Windows preset path resolution when the preset uses subpath exports.
Fixes incorrect code coverage in coverage reports when using the projects config option.
pretty-format supports React 19 so snapshots of React components work properly.
Fixes errors when require() is called after the Jest environment has been torn down.
Subset matching no longer throws when encountering exotic iterables.
No longer fails on structuredClone results due to cross-realm constructor mismatch.
Virtual registrations are now respected in ESM.
Fixes dynamic import when the Node option
--experimental-vm-modulesis specified.Console output is now displayed for the GHA reporter when
silent: false.Preserves CLI coverage output when using
--jsonwith--outputFile.Failed tests due to compilation errors are re-executed when
--onlyFailuresis used.