Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion apps/site/authors.json
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@
"name": "Richard Lau",
"website": "https://github.com/richardlau"
},
"Richie McColl": {
"richiemccoll": {
"id": "richiemccoll",
"name": "Richie McColl",
"website": "https://github.com/richiemccoll"
Expand Down
32 changes: 11 additions & 21 deletions apps/site/pages/en/blog/migrations/chalk-to-styletext.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -50,31 +50,21 @@ npx codemod @nodejs/chalk-to-util-styletext

### Example:

```js displayName="Before"
import chalk from 'chalk';
```diff
- import chalk from 'chalk';
+ import { styleText } from 'node:util';

console.log(chalk.red('Error message'));
- console.log(chalk.red('Error message'));
+ console.log(styleText('red', 'Error message'));

console.log(chalk.red.bold('Important error'));
- console.log(chalk.green.underline('Success with emphasis'));
+ console.log(styleText(['green', 'underline'], 'Success with emphasis'));

const red = chalk.red;
- const red = chalk.red;
+ const red = (text) => styleText('red', text);
- const boldBlue = chalk.blue.bold;
+ const boldBlue = (text) => styleText(['blue', 'bold'], text);
console.log(red('Error'));

const boldBlue = chalk.blue.bold;
console.log(boldBlue('Info'));
```

```js displayName="After"
import { styleText } from 'node:util';

console.log(styleText('red', 'Error message'));

console.log(styleText(['red', 'bold'], 'Important error'));

const red = text => styleText('red', text);
console.log(red('Error'));

const boldBlue = text => styleText(['blue', 'bold'], text);
console.log(boldBlue('Info'));
```

Expand Down
27 changes: 12 additions & 15 deletions apps/site/pages/en/blog/migrations/v12-to-v14.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,20 @@ The source code for this codemod can be found in the [util-print-to-console-log
You can find this codemod in the [Codemod Registry](https://app.codemod.com/registry/@nodejs/util-print-to-console-log).

```bash
npx codemod run @nodejs/create-require-from-path
npx codemod run @nodejs/util-print-to-console-log
```

### Example:

```js displayName="Before"
const util = require('node:util');

util.print('Hello world');
util.puts('Hello world');
util.debug('Hello world');
util.error('Hello world');
```

```js displayName="After"
console.log('Hello world');
console.log('Hello world');
console.error('Hello world');
console.error('Hello world');
```diff
- const util = require("node:util");

- util.print("Hello world");
+ console.log("Hello world");
- util.puts("Hello world");
+ console.log("Hello world");
- util.debug("Hello world");
+ console.error("Hello world");
- util.error("Hello world");
+ console.error("Hello world");
```
92 changes: 35 additions & 57 deletions apps/site/pages/en/blog/migrations/v14-to-v16.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,15 @@ npx codemod run @nodejs/create-require-from-path

### Example:

```js displayName="Before"
import { createRequireFromPath } from 'node:module';
```diff
- const { createRequireFromPath } = require('node:module');
+ const { createRequire } = require('node:module');

const requireFromPath = createRequireFromPath('/path/to/module');
const myModule = requireFromPath('./myModule.cjs');
```

```js displayName="After"
import { createRequire } from 'node:module';
- const requireFromPath = createRequireFromPath('/path/to/module');
+ const require = createRequire('/path/to/module');

const require = createRequire('/path/to/module');
const myModule = require('./myModule.cjs');
- const myModule = requireFromPath('./myModule.cjs');
+ const myModule = require('./myModule.cjs');
```

## `process-main-module`
Expand All @@ -60,20 +57,13 @@ npx codemod run @nodejs/process-main-module

### Example:

```js displayName="Before"
if (process.mainModule === 'mod.js') {
// cli thing
} else {
// module thing
}
```

```js displayName="After"
if (require.main === 'mod.js') {
// cli thing
} else {
// module thing
}
```diff
- if (process.mainModule === "mod.js") {
+ if (require.main === "mod.js") {
// cli thing
} else {
// module thing
}
```

## `rmdir`
Expand All @@ -92,30 +82,21 @@ npx codemod run @nodejs/rmdir

### Example:

```js displayName="Before"
const fs = require('node:fs');

// Using fs.rmdir with the recursive option
fs.rmdir(path, { recursive: true }, callback);

// Using fs.rmdirSync with the recursive option
fs.rmdirSync(path, { recursive: true });

// Using fs.promises.rmdir with the recursive option
fs.promises.rmdir(path, { recursive: true });
```

```js displayName="After"
const fs = require('node:fs');

// Using fs.rm with recursive and force options
fs.rm(path, { recursive: true, force: true }, callback);

// Using fs.rmSync with recursive and force options
fs.rmSync(path, { recursive: true, force: true });

// Using fs.promises.rm with recursive and force options
fs.promises.rm(path, { recursive: true, force: true });
```diff
// Using fs.rmdir with the recursive option
- fs.rmdir(path, { recursive: true }, callback);
+ // Using fs.rm with recursive and force options
+ fs.rm(path, { recursive: true, force: true }, callback);

// Using fs.rmdirSync with the recursive option
- fs.rmdirSync(path, { recursive: true });
+ // Using fs.rmSync with recursive and force options
+ fs.rmSync(path, { recursive: true, force: true });

// Using fs.promises.rmdir with the recursive option
- fs.promises.rmdir(path, { recursive: true });
+ // Using fs.promises.rm with recursive and force options
+ fs.promises.rm(path, { recursive: true, force: true });
```

## `tmpDir-to-tmpdir`
Expand All @@ -134,14 +115,11 @@ npx codemod run @nodejs/tmpDir-to-tmpdir

### Example:

```js displayName="Before"
import { tmpDir } from 'node:os';

const foo = tmpDir();
```diff
- import { tmpDir } from 'node:os';
+ import { tmpdir } from 'node:os';
- const foo = tmpDir()
+ const foo = tmpdir()
```

```js displayName="After"
import { tmpdir } from 'node:os';

const foo = tmpdir();
```
reateRequireFromPath
Comment thread
AugustinMauroy marked this conversation as resolved.
Outdated
51 changes: 51 additions & 0 deletions apps/site/pages/en/blog/migrations/v16-to-v18.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
date: '2025-10-28T00:02:00.000Z'
category: migrations
title: Node.js v16 to v18
layout: blog-post
author: AugustinMauroy
---

# Node.js v16 to v18

<AlertBox level="info" title="!">
This article covers a part of the migration from Node.js v16 to v18. The
userland migrations team is working on more codemods to help you with the
migration.
</AlertBox>

This page provides a list of codemods to help you migrate your code from Node.js v16 to v18.

## `err-invalid-callback`

In Node.js v18, the [DEP0159](https://nodejs.org/api/deprecations.html#DEP0159) deprecation was introduced, which deprecated the `ERR_INVALID_CALLBACK` error code in favor of `ERR_INVALID_ARG_TYPE`. This codemod will help you replace any references to the old error code with the new one.

The source code for this codemod can be found in the [err-invalid-callback directory](https://github.com/nodejs/userland-migrations/tree/main/recipes/err-invalid-callback).

You can find this codemod in the [Codemod Registry](https://app.codemod.com/registry/@nodejs/err-invalid-callback).

```bash
npx codemod run @nodejs/err-invalid-callback
```

### Example:

```diff
try {
fs.readFile("file.txt", "invalid-callback");
} catch (err) {
- if (err.code === "ERR_INVALID_CALLBACK") {
+ if (err.code === "ERR_INVALID_ARG_TYPE") {
console.error("Invalid callback provided");
}
}
```

Also handles deduplication when both codes were already checked:

```diff
const isCallbackError =
- err.code === "ERR_INVALID_CALLBACK" ||
- err.code === "ERR_INVALID_ARG_TYPE";
+ err.code === "ERR_INVALID_ARG_TYPE";
```
49 changes: 44 additions & 5 deletions apps/site/pages/en/blog/migrations/v20-to-v22.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
date: '2025-10-28T00:02:00.000Z'
date: '2025-10-28T00:03:00.000Z'
category: migrations
title: Node.js v20 to v22
layout: blog-post
Expand Down Expand Up @@ -34,10 +34,49 @@ npx codemod run @nodejs/import-assertions-to-attributes

### Example:

```js displayName="Before"
import jsonData from './data.json' assert { type: 'json' };
```diff
- import data from './data.json' assert { type: 'json' };
+ import data from './data.json' with { type: 'json' };
```

```js displayName="After"
import jsonData from './data.json' with { type: 'json' };
## `crypto-createcipheriv-migration`

Migrates deprecated `crypto.createCipher()` / `crypto.createDecipher()` usage to the supported `crypto.createCipheriv()` / `crypto.createDecipheriv()` APIs with explicit key derivation and IV handling.

Node.js removed `crypto.createCipher()` and `crypto.createDecipher()` in v22.0.0 ([DEP0106](https://nodejs.org/api/deprecations.html#DEP0106)). The legacy helpers derived keys with MD5 and no salt, and silently reused static IVs. This codemod replaces those calls with the modern, explicit APIs and scaffolds secure key derivation and IV management.

The source code for this codemod can be found in the [crypto-createcipheriv-migration directory](https://github.com/nodejs/userland-migrations/tree/main/recipes/crypto-createcipheriv-migration).

You can find this codemod in the [Codemod Registry](https://app.codemod.com/registry/@nodejs/crypto-createcipheriv-migration).

```bash
npx codemod run @nodejs/crypto-createcipheriv-migration
```

### What it does

- Replaces invocations of `createCipher()` / `createDecipher()` with `createCipheriv()` / `createDecipheriv()`.
- Inserts scaffolding that derives keys with `crypto.scryptSync()` and generates random salts and IVs.
- Reminds developers to persist salt + IV for decryption and to adjust key/IV lengths per algorithm.
- Updates destructured imports to include the new helpers (`createCipheriv`, `createDecipheriv`, `randomBytes`, `scryptSync`).

### Example

```diff
-const cipher = crypto.createCipher(algorithm, password);
+const cipher = (() => {
+ const __dep0106Salt = crypto.randomBytes(16);
+ const __dep0106Key = crypto.scryptSync(password, __dep0106Salt, 32);
+ const __dep0106Iv = crypto.randomBytes(16);
+ // DEP0106: Persist __dep0106Salt and __dep0106Iv alongside the ciphertext so it can be decrypted later.
+ return crypto.createCipheriv(algorithm, __dep0106Key, __dep0106Iv);
+})();
```

### Important notes

- The codemod cannot guarantee algorithm-specific key/IV sizes. Review the generated `scryptSync` length and IV length defaults and adjust as needed.
- Decryption snippets include placeholders (`Buffer.alloc(16)`) that must be replaced with the salt and IV stored during encryption.
- If your project already wraps key derivation logic, you may prefer to adapt the generated scaffolding to call existing helpers.
- The generated code is not backward-compatible and will be unable to decrypt data that was encrypted using `createCipher()`.
- The use of scrypt is one possible choice for deriving a key from a password, but you may wish to use Argon2id or PBKDF2 instead.
Loading
Loading