JavaScript & TypeScript · Comparison
Node.js test runner vs Jest
Use node:test for Node.js libraries and services, and keep Jest for React components and heavy module mocking. Features and coverage compared on the same tests.
Node.js test runner or Jest?
Use the built-in runner, node:test, for Node.js libraries, command-line
tools and services: it has been stable since Node.js 20 and needs no
dependency. Keep Jest for React and React Native component tests, for suites
that lean on jest.mock, and for any suite that already works.
The same test in both
const { test } = require('node:test');
const assert = require('node:assert/strict');
const { canAccess } = require('./src/access');
test('signed-out session cannot access', () => {
assert.equal(canAccess(false, false), false);
});const { canAccess } = require('./src/access');
test('signed-out session cannot access', () => {
expect(canAccess(false, false)).toBe(false);
});
Run them with node --test and npx jest.
What differs
node:test on Node.js 24 | Jest 30 | |
|---|---|---|
| Install | Built in | npm install -D jest |
| Assertions | node:assert | expect and its matchers |
| Function and timer mocks | mock.fn, mock.timers | jest.fn, fake timers |
| Module mocks | mock.module, behind a flag, early development | jest.mock |
| Snapshots | t.assert.snapshot | toMatchSnapshot |
| Browser-like DOM | Not included | jest-environment-jsdom |
| ES modules | Native | Experimental, behind a Node.js flag |
| Coverage | --experimental-test-coverage | --coverage |
Sources: the Node.js test runner and Jest documentation.
Coverage differs most
The same three tests on one file, on Node.js 24.21.0 and Jest 30.5.2:
| Command | Lines | Branches | Functions |
|---|---|---|---|
node --test --experimental-test-coverage | 14/17 (82.35%) | 5/6 (83.33%) | 2/3 (66.67%) |
jest --coverage | 5/5 (100%) | 6/7 (85.71%) | 2/2 (100%) |
jest --coverage --coverageProvider=v8 | 14/17 (82.35%) | 4/5 (80%) | 2/3 (66.66%) |
Node.js reads coverage from the V8 engine, as Jest’s V8 provider does. Jest’s default instruments the source with Babel and counts statements, which is why its totals are smaller. Jest coverage: V8 vs Babel explains the gap.
Two practical differences:
- Status. Coverage in
node:testis still marked experimental. It prints a summary and can write lcov. Jest can use any Istanbul reporter, including HTML and Cobertura. - Ignore comments. Node.js reads
/* node:coverage ignore next */. Jest reads/* istanbul ignore next */with Babel and/* c8 ignore next */with V8.
Moving from Jest
Move files that use only test, describe and simple expect calls first.
Leave files that need jest.mock, jsdom or custom matchers on Jest. The two
runners can share a repository while you migrate.
Coverage per test in either runner
npx supercov -- node --test
npx supercov -- npx jest
Supercov measures both runners per test, with line, branch and MC/DC coverage, and keeps your configuration. On the file above it reported 7/9 lines, 4/6 branches and 1/3 MC/DC conditions under Jest.
Choosing between Jest and Vitest? See Vitest vs Jest. For the built-in runner against Vitest, see Node.js test runner vs Vitest.
Example evidence: fixture source, commands and recorded results (JSON). Measured October 12, 2026 with Supercov 4.3.0. These small examples are not a performance benchmark or a general conformance test.