Repository: nodejs/node
Pull request: doc: add esm examples to `node:util`

This PR adds the missing `ESM` counterparts of the `CJS` examples for [the Util documentation](https://nodejs.org/api/util.html).

I also destructured the (`require`)  imports for the current `CJS` examples following a feedback I had received in previous PRs.

For the `numericSeparator` example of [`util.inspect(object[, showHidden[, depth[, colors]]])`](https://nodejs.org/api/util.html#utilinspectobject-showhidden-depth-colors) I took the liberty to leave the numbers like this:
```js
const thousand = 1000;
const million = 1000000;
...
```

Instead of:
```js
const thousand = 1_000;
const million = 1_000_000;
...
```

Because that's actually what we want to showcase, how `numericSeparator` would add the missing underscores to print:
```bash
1_000
1_000_000
...
```

For the `Box` and `util.inspect.custom` examples at [Custom inspection functions on objects](https://nodejs.org/api/util.html#custom-inspection-functions-on-objects) I added a final `console.log` so users don't have to add it themselves when _copy/pasting_ the example to see an output.

For the [`util.inspect.defaultOptions`](https://nodejs.org/api/util.html#utilinspectdefaultoptions) example I incremented the number of 0's to be added just so the output is more _dramatic_ and it would showcase the function better imo, it would also print a square on the terminal which looks pretty awesome:
```bash
[
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0,
  ... 56 more items
]
[
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
```

For the _`promisify()` class methods that use this_ example at [`util.promisify(original)`](https://nodejs.org/api/util.html#utilpromisifyoriginal), the one with:
```js
class Foo {
  constructor() {
    this.a = 42;
  }

  bar(callback) {
    callback(null, this.a);
  }
}
...
```

I updated the error message, since now it's: `TypeError: Cannot read properties of undefined (reading 'a')` instead of `TypeError: Cannot read property 'a' of undefined`.

Lastly, for the [`util.styleText(format, text[, options])`](https://nodejs.org/api/util.html#utilstyletextformat-text-options) there was a typo on the example that [recently got fixed](https://github.com/nodejs/node/pull/56720) but only for the `ESM` part, this adds the `CJS` fix for that typo.

I think that's all, tell me what you think and I can update/change things around!

I've tested every single example and they all work/behave as expected.

As always, best regards :green_heart: 

Edit:
For the [`util.deprecate(fn, msg[, code])`](https://nodejs.org/api/util.html#utildeprecatefn-msg-code) example (the second one) I also added the functions and messages so users can just copy/paste that portion of code and run it without encountering errors.

Changed files:
filename: doc/api/util.md
patch: @@ -10,7 +10,11 @@ The `node:util` module supports the needs of Node.js internal APIs. Many of the
 utilities are useful for application and module developers as well. To access
 it:
 
-```js
+```mjs
+import util from 'node:util';
+```
+
+```cjs
 const util = require('node:util');
 ```
 
@@ -29,13 +33,27 @@ an `(err, value) => ...` callback as the last argument. In the callback, the
 first argument will be the rejection reason (or `null` if the `Promise`
 resolved), and the second argument will be the resolved value.
 
-```js
-const util = require('node:util');
+```mjs
+import { callbackify } from 'node:util';
 
 async function fn() {
   return 'hello world';
 }
-const callbackFunction = util.callbackify(fn);
+const callbackFunction = callbackify(fn);
+
+callbackFunction((err, ret) => {
+  if (err) throw err;
+  console.log(ret);
+});
+```
+
+```cjs
+const { callbackify } = require('node:util');
+
+async function fn() {
+  return 'hello world';
+}
+const callbackFunction = callbackify(fn);
 
 callbackFunction((err, ret) => {
   if (err) throw err;
@@ -89,11 +107,18 @@ environment variable. If the `section` name appears within the value of that
 environment variable, then the returned function operates similar to
 [`console.error()`][]. If not, then the returned function is a no-op.
 
-```js
-const util = require('node:util');
-const debuglog = util.debuglog('foo');
+```mjs
+import { debuglog } from 'node:util';
+const log = debuglog('foo');
+
+log('hello from foo [%d]', 123);
+```
+
+```cjs
+const { debuglog } = require('node:util');
+const log = debuglog('foo');
 
-debuglog('hello from foo [%d]', 123);
+log('hello from foo [%d]', 123);
 ```
 
 If this program is run with `NODE_DEBUG=foo` in the environment, then
@@ -108,11 +133,18 @@ environment variable set, then it will not print anything.
 
 The `section` supports wildcard also:
 
-```js
-const util = require('node:util');
-const debuglog = util.debuglog('foo-bar');
+```mjs
+import { debuglog } from 'node:util';
+const log = debuglog('foo');
 
-debuglog('hi there, it\'s foo-bar [%d]', 2333);
+log('hi there, it\'s foo-bar [%d]', 2333);
+```
+
+```cjs
+const { debuglog } = require('node:util');
+const log = debuglog('foo');
+
+log('hi there, it\'s foo-bar [%d]', 2333);
 ```
 
 if it is run with `NODE_DEBUG=foo*` in the environment, then it will output
@@ -129,12 +161,21 @@ The optional `callback` argument can be used to replace the logging function
 with a different function that doesn't have any initialization or
 unnecessary wrapping.
 
-```js
-const util = require('node:util');
-let debuglog = util.debuglog('internals', (debug) => {
+```mjs
+import { debuglog } from 'node:util';
+let log = debuglog('internals', (debug) => {
   // Replace with a logging function that optimizes out
   // testing if the section is enabled
-  debuglog = debug;
+  log = debug;
+});
+```
+
+```cjs
+const { debuglog } = require('node:util');
+let log = debuglog('internals', (debug) => {
+  // Replace with a logging function that optimizes out
+  // testing if the section is enabled
+  log = debug;
 });
 ```
 
@@ -152,9 +193,17 @@ If the `section` name appears within the value of that environment variable,
 then the returned value will be `true`. If not, then the returned value will be
 `false`.
 
-```js
-const util = require('node:util');
-const enabled = util.debuglog('foo').enabled;
+```mjs
+import { debuglog } from 'node:util';
+const enabled = debuglog('foo').enabled;
+if (enabled) {
+  console.log('hello from foo [%d]', 123);
+}
+```
+
+```cjs
+const { debuglog } = require('node:util');
+const enabled = debuglog('foo').enabled;
 if (enabled) {
   console.log('hello from foo [%d]', 123);
 }
@@ -196,10 +245,18 @@ changes:
 The `util.deprecate()` method wraps `fn` (which may be a function or class) in
 such a way that it is marked as deprecated.
 
-```js
-const util = require('node:util');
+```mjs
+import { deprecate } from 'node:util';
 
-exports.obsoleteFunction = util.deprecate(() => {
+export const obsoleteFunction = deprecate(() => {
+  // Do something here.
+}, 'obsoleteFunction() is deprecated. Use newShinyFunction() instead.');
+```
+
+```cjs
+const { deprecate } = require('node:util');
+
+exports.obsoleteFunction = deprecate(() => {
   // Do something here.
 }, 'obsoleteFunction() is deprecated. Use newShinyFunction() instead.');
 ```
@@ -213,11 +270,40 @@ emitting a warning.
 If the same optional `code` is supplied in multiple calls to `util.deprecate()`,
 the warning will be emitted only once for that `code`.
 
-```js
-const util = require('node:util');
+```mjs
+import { deprecate } from 'node:util';
+
+const fn1 = deprecate(
+  () => 'a value',
+  'deprecation message',
+  'DEP0001',
+);
+const fn2 = deprecate(
+  () => 'a  different value',
+  'other dep message',
+  'DEP0001',
+);
+fn1(); // Emits a deprecation warning with code DEP0001
+fn2(); // Does not emit a deprecation warning because it has the same code
+```
 
-const fn1 = util.deprecate(someFunction, someMessage, 'DEP0001');
-const fn2 = util.deprecate(someOtherFunction, someOtherMessage, 'DEP0001');
+```cjs
+const { deprecate } = require('node:util');
+
+const fn1 = deprecate(
+  function() {
+    return 'a value';
+  },
+  'deprecation message',
+  'DEP0001',
+);
+const fn2 = deprecate(
+  function() {
+    return 'a  different value';
+  },
+  'other dep message',
+  'DEP0001',
+);
 fn1(); // Emits a deprecation warning with code DEP0001
 fn2(); // Does not emit a deprecation warning because it has the same code
 ```
@@ -404,19 +490,56 @@ changes:
 Returns an array of call site objects containing the stack of
 the caller function.
 
-```js
-const util = require('node:util');
+```mjs
+import { getCallSites } from 'node:util';
 
 function exampleFunction() {
-  const callSites = util.getCallSites();
+  const callSites = getCallSites();
 
   console.log('Call Sites:');
   callSites.forEach((callSite, index) => {
     console.log(`CallSite ${index + 1}:`);
     console.log(`Function Name: ${callSite.functionName}`);
     console.log(`Script Name: ${callSite.scriptName}`);
     console.log(`Line Number: ${callSite.lineNumber}`);
-    console.log(`Column Number: ${callSite.columnNumber}`);
+    console.log(`Column Number: ${callSite.column}`);
+  });
+  // CallSite 1:
+  // Function Name: exampleFunction
+  // Script Name: /home/example.js
+  // Line Number: 5
+  // Column Number: 26
+
+  // CallSite 2:
+  // Function Name: anotherFunction
+  // Script Name: /home/example.js
+  // Line Number: 22
+  // Column Number: 3
+
+  // ...
+}
+
+// A function to simulate another stack layer
+function anotherFunction() {
+  exampleFunction();
+}
+
+anotherFunction();
+```
+
+```cjs
+const { getCallSites } = require('node:util');
+
+function exampleFunction() {
+  const callSites = getCallSites();
+
+  console.log('Call Sites:');
+  callSites.forEach((callSite, index) => {
+    console.log(`CallSite ${index + 1}:`);
+    console.log(`Function Name: ${callSite.functionName}`);
+    console.log(`Script Name: ${callSite.scriptName}`);
+    console.log(`Line Number: ${callSite.lineNumber}`);
+    console.log(`Column Number: ${callSite.column}`);
   });
   // CallSite 1:
   // Function Name: exampleFunction
@@ -447,13 +570,31 @@ When the `--enable-source-maps` flag is enabled, for example when using `--exper
 `sourceMap` will be true by default.
 
 ```ts
-import util from 'node:util';
+import { getCallSites } from 'node:util';
 
 interface Foo {
   foo: string;
 }
 
-const callSites = util.getCallSites({ sourceMap: true });
+const callSites = getCallSites({ sourceMap: true });
+
+// With sourceMap:
+// Function Name: ''
+// Script Name: example.js
+// Line Number: 7
+// Column Number: 26
+
+// Without sourceMap:
+// Function Name: ''
+// Script Name: example.js
+// Line Number: 2
+// Column Number: 26
+```
+
+```cjs
+const { getCallSites } = require('node:util');
+
+const callSites = getCallSites({ sourceMap: true });
 
 // With sourceMap:
 // Function Name: ''
@@ -587,7 +728,24 @@ stream.write('It works!'); // Received data: "It works!"
 
 ES6 example using `class` and `extends`:
 
-```js
+```mjs
+import EventEmitter from 'node:events';
+
+class MyStream extends EventEmitter {
+  write(data) {
+    this.emit('data', data);
+  }
+}
+
+const stream = new MyStream();
+
+stream.on('data', (data) => {
+  console.log(`Received data: "${data}"`);
+});
+stream.write('With ES6');
+```
+
+```cjs
 const EventEmitter = require('node:events');
 
 class MyStream extends EventEmitter {
@@ -770,7 +928,23 @@ util.inspect(baz);       // '[foo] {}'
 
 Circular references point to their anchor by using a reference index:
 
-```js
+```mjs
+import { inspect } from 'node:util';
+
+const obj = {};
+obj.a = [obj];
+obj.b = {};
+obj.b.inner = obj.b;
+obj.b.obj = obj;
+
+console.log(inspect(obj));
+// <ref *1> {
+//   a: [ [Circular *1] ],
+//   b: <ref *2> { inner: [Circular *2], obj: [Circular *1] }
+// }
+```
+
+```cjs
 const { inspect } = require('node:util');
 
 const obj = {};
@@ -788,16 +962,72 @@ console.log(inspect(obj));
 
 The following example inspects all properties of the `util` object:
 
-```js
+```mjs
+import util from 'node:util';
+
+console.log(util.inspect(util, { showHidden: true, depth: null }));
+```
+
+```cjs
 const util = require('node:util');
 
 console.log(util.inspect(util, { showHidden: true, depth: null }));
 ```
 
 The following example highlights the effect of the `compact` option:
 
-```js
-const util = require('node:util');
+```mjs
+import { inspect } from 'node:util';
+
+const o = {
+  a: [1, 2, [[
+    'Lorem ipsum dolor sit amet,\nconsectetur adipiscing elit, sed do ' +
+      'eiusmod \ntempor incididunt ut labore et dolore magna aliqua.',
+    'test',
+    'foo']], 4],
+  b: new Map([['za', 1], ['zb', 'test']]),
+};
+console.log(inspect(o, { compact: true, depth: 5, breakLength: 80 }));
+
+// { a:
+//   [ 1,
+//     2,
+//     [ [ 'Lorem ipsum dolor sit amet,\nconsectetur [...]', // A long line
+//           'test',
+//           'foo' ] ],
+//     4 ],
+//   b: Map(2) { 'za' => 1, 'zb' => 'test' } }
+
+// Setting `compact` to false or an integer creates more reader friendly output.
+console.log(inspect(o, { compact: false, depth: 5, breakLength: 80 }));
+
+// {
+//   a: [
+//     1,
+//     2,
+//     [
+//       [
+//         'Lorem ipsum dolor sit amet,\n' +
+//           'consectetur adipiscing elit, sed do eiusmod \n' +
+//           'tempor incididunt ut labore et dolore magna aliqua.',
+//         'test',
+//         'foo'
+//       ]
+//     ],
+//     4
+//   ],
+//   b: Map(2) {
+//     'za' => 1,
+//     'zb' => 'test'
+//   }
+// }
+
+// Setting `breakLength` to e.g. 150 will print the "Lorem ipsum" text in a
+// single line.
+```
+
+```cjs
+const { inspect } = require('node:util');
 
 const o = {
   a: [1, 2, [[
@@ -807,7 +1037,7 @@ const o = {
     'foo']], 4],
   b: new Map([['za', 1], ['zb', 'test']]),
 };
-console.log(util.inspect(o, { compact: true, depth: 5, breakLength: 80 }));
+console.log(inspect(o, { compact: true, depth: 5, breakLength: 80 }));
 
 // { a:
 //   [ 1,
@@ -819,7 +1049,7 @@ console.log(util.inspect(o, { compact: true, depth: 5, breakLength: 80 }));
 //   b: Map(2) { 'za' => 1, 'zb' => 'test' } }
 
 // Setting `compact` to false or an integer creates more reader friendly output.
-console.log(util.inspect(o, { compact: false, depth: 5, breakLength: 80 }));
+console.log(inspect(o, { compact: false, depth: 5, breakLength: 80 }));
 
 // {
 //   a: [
@@ -852,7 +1082,18 @@ guarantee which entries are displayed. That means retrieving the same
 {WeakSet} entries twice may result in different output. Furthermore, entries
 with no remaining strong references may be garbage collected at any time.
 
-```js
+```mjs
+import { inspect } from 'node:util';
+
+const obj = { a: 1 };
+const obj2 = { b: 2 };
+const weakSet = new WeakSet([obj, obj2]);
+
+console.log(inspect(weakSet, { showHidden: true }));
+// WeakSet { { a: 1 }, { b: 2 } }
+```
+
+```cjs
 const { inspect } = require('node:util');
 
 const obj = { a: 1 };
@@ -866,7 +1107,32 @@ console.log(inspect(weakSet, { showHidden: true }));
 The `sorted` option ensures that an object's property insertion order does not
 impact the result of `util.inspect()`.
 
-```js
+```mjs
+import { inspect } from 'node:util';
+import assert from 'node:assert';
+
+const o1 = {
+  b: [2, 3, 1],
+  a: '`a` comes before `b`',
+  c: new Set([2, 3, 1]),
+};
+console.log(inspect(o1, { sorted: true }));
+// { a: '`a` comes before `b`', b: [ 2, 3, 1 ], c: Set(3) { 1, 2, 3 } }
+console.log(inspect(o1, { sorted: (a, b) => b.localeCompare(a) }));
+// { c: Set(3) { 3, 2, 1 }, b: [ 2, 3, 1 ], a: '`a` comes before `b`' }
+
+const o2 = {
+  c: new Set([2, 1, 3]),
+  a: '`a` comes before `b`',
+  b: [2, 3, 1],
+};
+assert.strict.equal(
+  inspect(o1, { sorted: true }),
+  inspect(o2, { sorted: true }),
+);
+```
+
+```cjs
 const { inspect } = require('node:util');
 const assert = require('node:assert');
 
@@ -894,13 +1160,31 @@ assert.strict.equal(
 The `numericSeparator` option adds an underscore every three digits to all
 numbers.
 
-```js
+```mjs
+import { inspect } from 'node:util';
+
+const thousand = 1000;
+const million = 1000000;
+const bigNumber = 123456789n;
+const bigDecimal = 1234.12345;
+
+console.log(inspect(thousand, { numericSeparator: true }));
+// 1_000
+console.log(inspect(million, { numericSeparator: true }));
+// 1_000_000
+console.log(inspect(bigNumber, { numericSeparator: true }));
+// 123_456_789n
+console.log(inspect(bigDecimal, { numericSeparator: true }));
+// 1_234.123_45
+```
+
+```cjs
 const { inspect } = require('node:util');
 
-const thousand = 1_000;
-const million = 1_000_000;
-const bigNumber = 123_456_789n;
-const bigDecimal = 1_234.123_45;
+const thousand = 1000;
+const million = 1000000;
+const bigNumber = 123456789n;
+const bigDecimal = 1234.12345;
 
 console.log(inspect(thousand, { numericSeparator: true }));
 // 1_000
@@ -1026,15 +1310,46 @@ Objects may also define their own
 which `util.inspect()` will invoke and use the result of when inspecting
 the object.
 
-```js
-const util = require('node:util');
+```mjs
+import { inspect } from 'node:util';
+
+class Box {
+  constructor(value) {
+    this.value = value;
+  }
+
+  [inspect.custom](depth, options, inspect) {
+    if (depth < 0) {
+      return options.stylize('[Box]', 'special');
+    }
+
+    const newOptions = Object.assign({}, options, {
+      depth: options.depth === null ? null : options.depth - 1,
+    });
+
+    // Five space padding because that's the size of "Box< ".
+    const padding = ' '.repeat(5);
+    const inner = inspect(this.value, newOptions)
+                  .replace(/\n/g, `\n${padding}`);
+    return `${options.stylize('Box', 'special')}< ${inner} >`;
+  }
+}
+
+const box = new Box(true);
+
+console.log(inspect(box));
+// "Box< true >"
+```
+
+```cjs
+const { inspect } = require('node:util');
 
 class Box {
   constructor(value) {
     this.value = value;
   }
 
-  [util.inspect.custom](depth, options, inspect) {
+  [inspect.custom](depth, options, inspect) {
     if (depth < 0) {
       return options.stylize('[Box]', 'special');
     }
@@ -1053,24 +1368,36 @@ class Box {
 
 const box = new Box(true);
 
-util.inspect(box);
-// Returns: "Box< true >"
+console.log(inspect(box));
+// "Box< true >"
 ```
 
 Custom `[util.inspect.custom](depth, opts, inspect)` functions typically return
 a string but may return a value of any type that will be formatted accordingly
 by `util.inspect()`.
 
-```js
-const util = require('node:util');
+```mjs
+import { inspect } from 'node:util';
 
 const obj = { foo: 'this will not show up in the inspect() output' };
-obj[util.inspect.custom] = (depth) => {
+obj[inspect.custom] = (depth) => {
   return { bar: 'baz' };
 };
 
-util.inspect(obj);
-// Returns: "{ bar: 'baz' }"
+console.log(inspect(obj));
+// "{ bar: 'baz' }"
+```
+
+```cjs
+const { inspect } = require('node:util');
+
+const obj = { foo: 'this will not show up in the inspect() output' };
+obj[inspect.custom] = (depth) => {
+  return { bar: 'baz' };
+};
+
+console.log(inspect(obj));
+// "{ bar: 'baz' }"
 ```
 
 ### `util.inspect.custom`
@@ -1130,12 +1457,21 @@ The `defaultOptions` value allows customization of the default options used by
 object containing one or more valid [`util.inspect()`][] options. Setting
 option properties directly is also supported.
 
-```js
-const util = require('node:util');
-const arr = Array(101).fill(0);
+```mjs
+import { inspect } from 'node:util';
+const arr = Array(156).fill(0);
 
 console.log(arr); // Logs the truncated array
-util.inspect.defaultOptions.maxArrayLength = null;
+inspect.defaultOptions.maxArrayLength = null;
+console.log(arr); // logs the full array
+```
+
+```cjs
+const { inspect } = require('node:util');
+const arr = Array(156).fill(0);
+
+console.log(arr); // Logs the truncated array
+inspect.defaultOptions.maxArrayLength = null;
 console.log(arr); // logs the full array
 ```
 
@@ -1777,12 +2113,24 @@ Takes a function following the common error-first callback style, i.e. taking
 an `(err, value) => ...` callback as the last argument, and returns a version
 that returns promises.
 
-```js
-const util = require('node:util');
-const fs = require('node:fs');
+```mjs
+import { promisify } from 'node:util';
+import { stat } from 'node:fs';
+
+const promisifiedStat = promisify(stat);
+promisifiedStat('.').then((stats) => {
+  // Do something with `stats`
+}).catch((error) => {
+  // Handle the error.
+});
+```
+
+```cjs
+const { promisify } = require('node:util');
+const { stat } = require('node:fs');
 
-const stat = util.promisify(fs.stat);
-stat('.').then((stats) => {
+const promisifiedStat = promisify(stat);
+promisifiedStat('.').then((stats) => {
   // Do something with `stats`
 }).catch((error) => {
   // Handle the error.
@@ -1791,14 +2139,28 @@ stat('.').then((stats) => {
 
 Or, equivalently using `async function`s:
 
-```js
-const util = require('node:util');
-const fs = require('node:fs');
+```mjs
+import { promisify } from 'node:util';
+import { stat } from 'node:fs';
+
+const promisifiedStat = promisify(stat);
+
+async function callStat() {
+  const stats = await promisifiedStat('.');
+  console.log(`This directory is owned by ${stats.uid}`);
+}
+
+callStat();
+```
+
+```cjs
+const { promisify } = require('node:util');
+const { stat } = require('node:fs');
 
-const stat = util.promisify(fs.stat);
+const promisifiedStat = promisify(stat);
 
 async function callStat() {
-  const stats = await stat('.');
+  const stats = await promisifiedStat('.');
   console.log(`This directory is owned by ${stats.uid}`);
 }
 
@@ -1817,8 +2179,8 @@ callback as its last argument.
 Using `promisify()` on class methods or other methods that use `this` may not
 work as expected unless handled specially:
 
-```js
-const util = require('node:util');
+```mjs
+import { promisify } from 'node:util';
 
 class Foo {
   constructor() {
@@ -1832,8 +2194,33 @@ class Foo {
 
 const foo = new Foo();
 
-const naiveBar = util.promisify(foo.bar);
-// TypeError: Cannot read property 'a' of undefined
+const naiveBar = promisify(foo.bar);
+// TypeError: Cannot read properties of undefined (reading 'a')
+// naiveBar().then(a => console.log(a));
+
+naiveBar.call(foo).then((a) => console.log(a)); // '42'
+
+const bindBar = naiveBar.bind(foo);
+bindBar().then((a) => console.log(a)); // '42'
+```
+
+```cjs
+const { promisify } = require('node:util');
+
+class Foo {
+  constructor() {
+    this.a = 42;
+  }
+
+  bar(callback) {
+    callback(null, this.a);
+  }
+}
+
+const foo = new Foo();
+
+const naiveBar = promisify(foo.bar);
+// TypeError: Cannot read properties of undefined (reading 'a')
 // naiveBar().then(a => console.log(a));
 
 naiveBar.call(foo).then((a) => console.log(a)); // '42'
@@ -1847,19 +2234,35 @@ bindBar().then((a) => console.log(a)); // '42'
 Using the `util.promisify.custom` symbol one can override the return value of
 [`util.promisify()`][]:
 
-```js
-const util = require('node:util');
+```mjs
+import { promisify } from 'node:util';
 
 function doSomething(foo, callback) {
   // ...
 }
 
-doSomething[util.promisify.custom] = (foo) => {
+doSomething[promisify.custom] = (foo) => {
   return getPromiseSomehow();
 };
 
-const promisified = util.promisify(doSomething);
-console.log(promisified === doSomething[util.promisify.custom]);
+const promisified = promisify(doSomething);
+console.log(promisified === doSomething[promisify.custom]);
+// prints 'true'
+```
+
+```cjs
+const { promisify } = require('node:util');
+
+function doSomething(foo, callback) {
+  // ...
+}
+
+doSomething[promisify.custom] = (foo) => {
+  return getPromiseSomehow();
+};
+
+const promisified = promisify(doSomething);
+console.log(promisified === doSomething[promisify.custom]);
 // prints 'true'
 ```
 
@@ -2604,12 +3007,24 @@ DECLARE_NAPI_PROPERTY("myNapi", MyNapi)
 ...
 ```
 
-```js
+```mjs
+import native from 'napi_addon.node';
+import { types } from 'node:util';
+
+const data = native.myNapi();
+types.isExternal(data); // returns true
+types.isExternal(0); // returns false
+types.isExternal(new String('foo')); // returns false
+```
+
+```cjs
 const native = require('napi_addon.node');
+const { types } = require('node:util');
+
 const data = native.myNapi();
-util.types.isExternal(data); // returns true
-util.types.isExternal(0); // returns false
-util.types.isExternal(new String('foo')); // returns false
+types.isExternal(data); // returns true
+types.isExternal(0); // returns false
+types.isExternal(new String('foo')); // returns false
 ```
 
 For further information on `napi_create_external`, refer to
@@ -2833,11 +3248,23 @@ returning `true` for that value. `isNativeError()` returns `true` for errors
 which come from a different [realm][] while `instanceof Error` returns `false`
 for these errors:
 
-```js
-const vm = require('node:vm');
-const context = vm.createContext({});
-const myError = vm.runInContext('new Error()', context);
-console.log(util.types.isNativeError(myError)); // true
+```mjs
+import { createContext, runInContext } from 'node:vm';
+import { types } from 'node:util';
+
+const context = createContext({});
+const myError = runInContext('new Error()', context);
+console.log(types.isNativeError(myError)); // true
+console.log(myError instanceof Error); // false
+```
+
+```cjs
+const { createContext, runInContext } = require('node:vm');
+const { types } = require('node:util');
+
+const context = createContext({});
+const myError = runInContext('new Error()', context);
+console.log(types.isNativeError(myError)); // true
 console.log(myError instanceof Error); // false
 ```