Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions apps/site/authors.json
Original file line number Diff line number Diff line change
Expand Up @@ -321,5 +321,10 @@
"id": 555645,
"name": "Yosuke Furukawa",
"website": "https://github.com/yosuke-furukawa"
},
"Xavier Stouder": {
"id": 2575182,
"name": "Xavier Stouder",
"website": "https://github.com/Xstoudi"
}
}
137 changes: 137 additions & 0 deletions apps/site/pages/en/blog/migrations/mocha-to-node-test-runner.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
---
date: '2026-08-06T00:00:00.000Z'
category: migrations
title: Mocha to Node.js Test Runner
layout: blog-post
author: Xavier Stouder
---

# Migrate from Mocha to the Node.js Test Runner

This codemod helps migrate test suites from [Mocha](https://mochajs.org/) to the built-in [Node.js test runner](https://nodejs.org/api/test.html). It updates common Mocha globals, imports the equivalent APIs from `node:test`, and helps projects reduce their dependency on an external test framework.

## Why doing this?

- **Native Support**: The Node.js test runner is built into Node.js, so many projects can run tests without installing Mocha.
- **Lower Maintenance**: Removing Mocha can reduce dependency updates and framework-specific configuration.
- **Standard Assertions**: The migration pairs naturally with `node:assert/strict`, which is also available in Node.js.
- **Built-in CLI**: Tests can be run with `node --test`, including support for filtering, watch mode, concurrency, and reporters.

## Node.js Version Requirements

- Node.js v18.0.0 or later (Node.js test runner is available but marked experimental)
- Node.js v20.0.0 or later (Node.js test runner is stable)

> If your package currently supports Node.js versions earlier than v18.0.0, you cannot migrate to the Node.js test runner without dropping support for those versions.
> This requires bumping the major version of your package AND updating the engines field in your package.json to require Node.js >= v18.0.0.
Comment on lines +20 to +26

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section isn't needed, since those versions are both EOL

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

humm IMO we should keep it because user may have older codebase that use EoL and to update it they can use this codemod.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's common for migrations to run to update outdated software in outdated environments.
Knowing that this migration won't work before node 20 -18 with experimental flag- would be valuable to me tbh. I can maybe agree that lines 25 and 26 are not that useful tho.


## Supported Transformations

The codemod supports the most common Mocha testing APIs and converts them to their `node:test` equivalents:

- `describe()`
- `it()`
- `before()`
- `after()`
- `beforeEach()`
- `afterEach()`
- `.skip()`
- `.only()`

It also inserts imports from `node:test` when a file relies on Mocha globals.

It also convert `this.timeout(N)` to `{ timeout: N }` options.

## Usage

The source code for this codemod can be found in the [mocha-to-node-test-runner directory](https://github.com/nodejs/userland-migrations/tree/main/recipes/mocha-to-node-test-runner).

You can find this codemod in the [Codemod Registry](https://app.codemod.com/registry/@nodejs/mocha-to-node-test-runner).

```bash
npx codemod @nodejs/mocha-to-node-test-runner
```

After running the codemod, update your test script to use the Node.js test runner:

```diff
{
"scripts": {
- "test": "mocha"
+ "test": "node --test"
}
}
```

## Examples

### Basic Test Suite

```diff
+ import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { sum } from './sum.js';

describe('sum', () => {
it('adds two numbers', () => {
assert.equal(sum(2, 3), 5);
});
});
```

### Lifecycle Hooks

```diff
+ import { after, before, beforeEach, describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { createServer } from './server.js';

describe('server', () => {
let server;

before(async () => {
server = await createServer();
});

beforeEach(() => {
server.reset();
});

after(async () => {
await server.close();
});

it('responds with health status', async () => {
const response = await server.inject('/health');

assert.equal(response.statusCode, 200);
});
});
```

### Skipped and Focused Tests

```diff
+ import { describe, it } from 'node:test';
import assert from 'node:assert/strict';

describe('feature flags', () => {
it.skip('handles a disabled flag', () => {
assert.equal(isEnabled('new-flow'), false);
});

it.only('handles an enabled flag', () => {
assert.equal(isEnabled('stable-flow'), true);
});
});
```

## Unsupported APIs

The codemod does not yet cover every Mocha feature. Projects that rely on custom reporters, root hook plugins, retries, `this.slow()`, or advanced Mocha configuration should review the transformed tests manually.

Mocha and the Node.js test runner also differ in their execution model, CLI options, and reporter configuration. After running the codemod, run the full test suite and review any project-specific test setup.

## Recognition

We would like to thank the maintainers of [Mocha](https://mochajs.org/) for their long-standing work on JavaScript testing and their contributions to the ecosystem.