Gutenberg’s JavaScript unit and integration tests now use Vitest

TL;DR

  • GutenbergGutenberg The Gutenberg project is the new Editor Interface for WordPress. The editor improves the process and experience of creating new content, making writing rich content much simpler. It uses ‘blocks’ to add richness rather than shortcodes, custom HTML etc. https://wordpress.org/gutenberg/’s JavaScriptJavaScript JavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com unit and integration tests now use Vitest, bringing better support for modern JavaScript modules and real-browser component testing.
  • Tests explicitly import Vitest APIs. Filenames select Node, jsdom, or Browser Mode according to what each test needs.
  • @wordpress/scripts 36.0.0 makes Vitest the default for test-unit-js. Projects install and configure their own test runner.
  • Existing projects can keep their Jest tests through test-unit-jest, after a one-time setup update. This command receives maintenance support and has no scheduled removal.
  • @wordpress/jest-preset-default and @wordpress/jest-console are deprecated. Published versions remain available for existing projects. No replacement WordPress Vitest preset or console packages are planned.

Following the initial announcement in #core-editor, Gutenberg has completed its migrationMigration Moving the code, database and media files for a website site from one server to another. Most typically done when changing hosting companies. from Jest to Vitest for JavaScript unit and integration tests.

The migration changes both Gutenberg’s test setup and the published WordPress test tooling. Most tests keep a familiar structure, with more explicit control over their environment.

Why Vitest?

Modern JavaScript module support and real-browser testing are two major benefits.

As more dependencies adopted ECMAScript modules, or ESM, Gutenberg’s CommonJS-based Jest setup needed additional compatibility configuration. For example, we maintained an explicit list of dependencies that Babel needed to transform for Jest. Updating a dependency could therefore require changes to the test configuration too.

Vitest’s native ESM support reduces the need for these workarounds. Tests run in Node by default, with DOM or browser environments selected explicitly when needed. This makes the test environment easier to understand and avoids supplying simulated browser behavior to tests that don’t need it.

Browser Mode runs focused unit and integration tests in a real browser. Component tests can check computed styles, element sizes, scrolling, focus, and keyboard interactions without recreating those behaviors through jsdom mocks. jsdom remains available for DOM tests that don’t depend on browser rendering.

Maintainability also matters. Jest’s maintainers have acknowledged a period of slower progress and fewer releases, though recent versions have brought performance and compatibility improvements. Gutenberg’s move to Vitest addresses longer-term needs: reducing custom compatibility configuration and sharing the Vite tooling already used by Storybook. Its Jest-compatible APIs also made an incremental migration possible.

The migration adds real-browser coverage while keeping test execution parallel. Browser Mode tests run alongside the Node and jsdom suites and, in our migration benchmarks, finished before the longest-running Node/jsdom group. Browser testing therefore did not determine the overall test completion time in that measured configuration. We also optimized test workers and shared setup to reduce runtime during the migration.

What changes for Gutenberg contributors?

Tests explicitly import APIs such as describe, test, expect, and vi from vitest. Some mocking APIs, assertions, and command-line options differ from Jest, so existing examples may need more than a change of imports.

Test filenames select the environment:

  • *.test.* without an environment suffix runs in Node.
  • *.jsdom.test.* runs in jsdom for DOM structure, events, and state that don’t depend on browser rendering.
  • *.browser.test.* runs in Browser Mode for real CSSCSS Cascading Style Sheets., layout, and browser-dependent interaction.

Browser Mode also requires a browser installation and uses different ReactReact React is a JavaScript library that makes it easy to reason about, construct, and maintain stateless and stateful user interfaces. https://reactjs.org rendering and interaction APIs from jsdom tests. The Testing Overview in the Block Editor Handbook covers setup, choosing an environment, and writing and running tests.

The main contributor commands remain npm test and npm run test:unit.

What changes for consumers of WordPress test tooling?

Starting with @wordpress/scripts 36.0.0, wp-scripts test-unit-js uses the project’s installed Vitest. This release includes breaking changes to test configuration, dependencies, APIs, and command-line options.

For a new test setup, start with the test-unit-js documentation. It explains installation and configuration and links to examples for Node, jsdom, and Browser Mode. Projects own their configuration and choose the environments and supporting dependencies they need.

Existing projects have two options:

  • Move to Vitest. Follow the migration guidance linked from the package documentation to update dependencies, configuration, tests, and commands.
  • Keep Jest. Switch Jest commands from wp-scripts test-unit-js to wp-scripts test-unit-jest, install the required Jest dependencies directly, and configure the project explicitly. Existing tests and snapshots can stay on Jest.

Keeping Jest requires more than renaming the command if your project relied on the defaults previously bundled with @wordpress/scripts. The package no longer supplies Jest, its environment, or the WordPress Jest configuration and transformer. The documented upgrade steps cover how to retain that setup using the published packages.

The public test-unit configuration in @wordpress/eslint-plugin 27.0.0 and the default wp-scripts lint-js unit-test rules also switch to Vitest. Projects keeping Jest need explicit Jest lint rules; the upgrade guidance covers these too.

test-unit-jest remains a maintenance-only command with no scheduled removal. New testing features target Vitest.

What happens to the WordPress Jest packages?

@wordpress/jest-preset-default and @wordpress/jest-console are deprecated and will no longer receive updates. Their published versions remain available for existing Jest projects.

Most of the functionality that motivated separate WordPress packages can now use Vitest’s built-in features and configuration. There are therefore no corresponding @wordpress/vitest-preset-default or @wordpress/vitest-console packages.

Some behavior still needs explicit setup. For example, Vitest’s spies can check expected console calls, but automatically failing tests on unexpected console output requires additional setup. The configuration examples explain which behavior projects need to configure themselves.

Questions and feedback

Comment here, ask in #core-editor, or comment directly on the migration tracking issue (#80855), which records the implementation and decisions behind this change.

Props to @manzoorwanijk, @aduth, @0mirka00, @jonsurrell, @tyxla, and @mamaduka for driving and reviewing this work, and to @aduth, @manzoorwanijk, @simison and @tyxla for reviewing this post.

#gutenberg, #jest, #testing, #vitest