unstale

npm / jest-runtime

jest-runtime

What changed in jest-runtime 30, from its official release notes, upgrade guides and advisories. Also covers jest-config. Sources checked 2026-10-18.

2 breaking1 new APIs and options1 performance6 behavior and defaults2 tooling39 fixes and other

See which of these apply to your code, ranked, in your agent:

npx @unstale/cli init

@unstale/cli on npm

jest-runtime 3051 changes

Breaking changes 2

  • 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.0release notes

  • Calls are routed through the sandbox and return its process and hooked node:module rather than host objects.

    30.5.0release notes

New APIs and options 1

  • Retries can now be applied to an entire describe block by passing entireDescribe: true.

    30.5.0release notes

Performance 1

  • A single require.cache proxy is shared across modules, alongside other changes to reduce per-require overhead.

    30.5.0release notes

Behavior and default changes 6

  • When no transformer claims a .ts, .mts, or .cts file, Jest strips its TypeScript types with Node.

    30.5.2release notes

  • 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.0release notes

  • The deprecation warning for JSON imports without an import attribute is emitted once per test file instead of once per worker.

    30.5.0release notes

  • 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.0release notes

  • Supports requiring ES modules on Node v24.9+.

    30.4.0release notes

  • 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.0release notes

Tooling 2

  • 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.0release notes

  • Validates TC39 import attributes on ESM imports, including with { type: 'json' }.

    30.4.0release notes

Fixes and other changes 39

  • Package imports specifiers like #dep are resolved under ESM again.

    30.5.1release notes

  • 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.0release notes

  • 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.0release notes

  • Files with untransformed ESM syntax now produce an actionable ERR_REQUIRE_ESM error instead of a generic unexpected token message.

    30.5.0release notes

  • 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.0release notes

  • 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.0release notes

  • A .js file containing ESM syntax without a type: module marker now falls back to native ESM.

    30.5.0release notes

  • Calling this after teardown now reports that no coverage was collected instead of returning an empty result.

    30.5.0release notes

  • 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.0release notes

  • Resolving a builtin with import.meta.resolve uses its node: specifier.

    30.5.0release notes

  • Module mocks instantiated inside jest.isolateModules or jest.isolateModulesAsync are now scoped to that block and do not outlive it.

    30.5.0release notes

  • When jest.mock or jest.unstable_mockModule receives an unresolvable module, the error now points at {virtual: true}.

    30.5.0release notes

  • The mock is applied when the mocked file itself is required and to statically imported data: URIs on Node 24.9+.

    30.5.0release notes

  • An async factory now runs once per module; if it rejects, the import fails rather than crashing the worker.

    30.5.0release notes

  • 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.0release notes

  • The resolver honors the module-sync export condition so require() loads the ESM entry point exposed by a package, as Node does.

    30.5.0release notes

  • module.children is populated with the modules a file loads, matching Node.

    30.5.0release notes

  • The sandboxed module.createRequire accepts every file: URL string, including one with a localhost authority, as Node does.

    30.5.0release notes

  • A CommonJS module's exports are available under the 'module.exports' named export when imported from ESM, matching Node 23+.

    30.5.0release notes

  • 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.0release notes

  • 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.0release notes

  • 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.0release notes

  • On Node versions earlier than 24.9, require() of ESM-marked files is supported through a transform fallback.

    30.5.0release notes

  • A require(esm) module that failed to evaluate is now hidden from require.cache, as in Node.

    30.5.0release notes

  • The test file itself now has a non-null require.main.

    30.5.0release notes

  • Injected globals are bound to the correct values when injectGlobals is false instead of being shifted by one position.

    30.5.0release notes

  • Fixes named imports from CJS modules when module.exports is a function with own-property exports.

    30.4.2release notes

  • For CJS-from-ESM, module.exports is always the ESM default; __esModule unwrapping is no longer applied, aligning behavior with Node.

    30.4.1release notes

  • Improves interop with __esModule/Babel default unwrapping, broader named-export coverage, and a shared CJS singleton across importers.

    30.4.0release notes

  • Fixes deadlocks and double-evaluation during concurrent ESM and wasm imports.

    30.4.0release notes

  • Fixes incorrect code coverage reports when using the projects config option.

    30.4.0release notes

  • Resolves expect and @jest/expect from the internal module registry so test-file imports share the same JestAssertionError as the global expect.

    30.4.0release notes

  • Ensures import() reports an error when called after the Jest environment has been torn down.

    30.4.0release notes

  • Loads .js files containing ESM syntax as native ESM even without a "type":"module" marker.

    30.4.0release notes

  • Applies moduleNameMapper when resolving modules with require.resolve() and the paths option.

    30.4.0release notes

  • On Node v24.9+, when the CJS parser rejects ESM syntax in a .js file, falls back to require(esm).

    30.4.0release notes

  • Fixes errors when require() is called after the Jest environment has been torn down.

    30.4.0release notes

  • Fixes virtual unstable_mockModule registrations not being respected in ESM.

    30.4.0release notes

  • Fixes dynamic import so users can use it when specifying Node’s --experimental-vm-modules option.

    30.3.0release notes