# What changed in jest-runtime

> 51 changes in jest-runtime 30 from its official release notes, upgrade guides and advisories: 2 breaking, 1 new APIs and options. Each one cited. Sources checked 2026-10-18. HTML: https://unstale.sh/npm/jest-runtime/

To see which of these apply to a repository, run `npx @unstale/cli init` in it.

## jest-runtime 30

### Breaking changes

- On Node 24.9+, resolution and import-attribute errors in an ESM graph surface before any CJS dependencies execute, matching Node's run-nothing-on-a-broken-graph behavior. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- Calls are routed through the sandbox and return its process and hooked node:module rather than host objects. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)

### New APIs and options

- Retries can now be applied to an entire describe block by passing entireDescribe: true. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)

### Performance

- A single require.cache proxy is shared across modules, alongside other changes to reduce per-require overhead. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)

### Behavior and default changes

- When no transformer claims a .ts, .mts, or .cts file, Jest strips its TypeScript types with Node. (30.5.2) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3052)
- The test file has import.meta.main set to true, while every module it loads has it set to false, matching Node 24+. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- The deprecation warning for JSON imports without an import attribute is emitted once per test file instead of once per worker. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- On Node 24.9+, automocking and manual __mocks__ files work for synchronously evaluable ESM graphs; graphs requiring async evaluation or async-only resolution or transformation still throw. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- Supports requiring ES modules on Node v24.9+. (30.4.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3040)
- On Node v24.9+, Jest uses synchronous evaluate() for ES modules without top-level await and prefers the synchronous transform path when a sync transformer is configured. (30.4.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3040)

### Tooling

- Calling module.register() or module.registerHooks() inside a test now throws an actionable error because those hooks affect Jest's loader rather than sandboxed requires. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- Validates TC39 import attributes on ESM imports, including with { type: 'json' }. (30.4.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3040)

### Fixes and other changes

- Package imports specifiers like #dep are resolved under ESM again. (30.5.1) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3051)
- ESM syntax in a type: commonjs package or .cjs file now produces the CJS parse error rather than loading as ESM, matching Node. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- These modules now provide import.meta.resolve and import.meta.jest, accept any-case mediatype parameters, and use Node's error codes for invalid data: URIs. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- Files with untransformed ESM syntax now produce an actionable ERR_REQUIRE_ESM error instead of a generic unexpected token message. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- ES modules are keyed by full URL, so query and fragment suffixes create distinct module instances as in Node and appear in import.meta.url. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- Cached ESM modules are checked before require() returns them, so evaluation errors are rethrown and modules left linked by a failed sibling are evaluated rather than returned with uninitialized bindings. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- A .js file containing ESM syntax without a type: module marker now falls back to native ESM. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- Calling this after teardown now reports that no coverage was collected instead of returning an empty result. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- import source and import.source() now fail with ERR_SOURCE_PHASE_NOT_DEFINED and an actionable message rather than V8's bare instantiation error. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- Resolving a builtin with import.meta.resolve uses its node: specifier. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- Module mocks instantiated inside jest.isolateModules or jest.isolateModulesAsync are now scoped to that block and do not outlive it. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- When jest.mock or jest.unstable_mockModule receives an unresolvable module, the error now points at {virtual: true}. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- The mock is applied when the mocked file itself is required and to statically imported data: URIs on Node 24.9+. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- An async factory now runs once per module; if it rejects, the import fails rather than crashing the worker. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- Imported JSON has its byte-order mark stripped and is parsed with the test realm's JSON, so its objects pass instanceof Object inside the test. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- The resolver honors the module-sync export condition so require() loads the ESM entry point exposed by a package, as Node does. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- module.children is populated with the modules a file loads, matching Node. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- The sandboxed module.createRequire accepts every file: URL string, including one with a localhost authority, as Node does. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- A CommonJS module's exports are available under the 'module.exports' named export when imported from ESM, matching Node 23+. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- Retries of require() on a top-level-await graph now report the original ERR_REQUIRE_ASYNC_MODULE rather than a spurious concurrent import error. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- A CommonJS module that requires an ES module still being loaded now throws ERR_REQUIRE_CYCLE_MODULE like Node instead of evaluating the module a second time. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- Requiring an ES module with a default export now provides a live-binding facade marked __esModule: true and serves the same object from require.cache, matching Node. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- On Node versions earlier than 24.9, require() of ESM-marked files is supported through a transform fallback. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- A require(esm) module that failed to evaluate is now hidden from require.cache, as in Node. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- The test file itself now has a non-null require.main. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- Injected globals are bound to the correct values when injectGlobals is false instead of being shifted by one position. (30.5.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3050)
- Fixes named imports from CJS modules when module.exports is a function with own-property exports. (30.4.2) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3042)
- For CJS-from-ESM, module.exports is always the ESM default; __esModule unwrapping is no longer applied, aligning behavior with Node. (30.4.1) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3041)
- Improves interop with __esModule/Babel default unwrapping, broader named-export coverage, and a shared CJS singleton across importers. (30.4.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3040)
- Fixes deadlocks and double-evaluation during concurrent ESM and wasm imports. (30.4.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3040)
- Fixes incorrect code coverage reports when using the projects config option. (30.4.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3040)
- Resolves expect and @jest/expect from the internal module registry so test-file imports share the same JestAssertionError as the global expect. (30.4.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3040)
- Ensures import() reports an error when called after the Jest environment has been torn down. (30.4.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3040)
- Loads .js files containing ESM syntax as native ESM even without a "type":"module" marker. (30.4.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3040)
- Applies moduleNameMapper when resolving modules with require.resolve() and the paths option. (30.4.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3040)
- On Node v24.9+, when the CJS parser rejects ESM syntax in a .js file, falls back to require(esm). (30.4.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3040)
- Fixes errors when require() is called after the Jest environment has been torn down. (30.4.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3040)
- Fixes virtual unstable_mockModule registrations not being respected in ESM. (30.4.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3040)
- Fixes dynamic import so users can use it when specifying Node’s --experimental-vm-modules option. (30.3.0) — [release notes](https://github.com/jestjs/jest/blob/15c3d19dc2803892a3d0b08b863dee85aea48215/CHANGELOG.md#3030)
