New in Node.js v18

New in Node.js v18

ยท

3 min read

Featured on daily.dev

Just yesterday, Node.js v18 was released as the current stable version. Here's a quick walkthrough of some of the new features.

Global fetch!

Node.js had a global fetch behind the --experimental-fetch flag, which would allow you to use the Browser Fetch API natively in Node.js. In v18, the experimental Fetch API is available by default.

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(response => response.json())
  .then(json => console.log(json))
(node:82823) ExperimentalWarning: The Fetch API is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
{ userId: 1, id: 1, title: 'delectus aut autem', completed: false }

You also get access to FormData, Headers, Request, and Response objects.

Access to the Web Streaming API

Node.js now has experimental support for the Web Streaming API

fetch('https://dev.to/api/articles?per_page=1000&page=1')
    .then(response => response.body)
    .then(rb => rb.getReader())
    .then(reader => {
        const stream = new ReadableStream({
            ...
        })
    })

Built-in testing

Node.js now has a built-in testing framework, accesible at import('node:test')

import test from 'node:test';
import assert from 'node:assert';

test('true is not false', async t => {
    assert.strictEqual(true, !false);
});
$ node test.js
(node:83584) ExperimentalWarning: The test runner is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
TAP version 13
ok 1 - true is not false
  ---
  duration_ms: 0.000730654
  ...
1..1
# tests 1
# pass 1
# fail 0
# skipped 0
# todo 0
# duration_ms 0.074570679

The output is in the TAP format. You can use the tap or faucet CLIs to pretty print it

$ npm i -g tap
$ tap test.js
index.js 2> (node:84725) ExperimentalWarning: The test runner is an experimental feature. This feature could change at any time
index.js 2> (Use `node --trace-warnings ...` to show where the warning was created)
 PASS  index.js 1 OK 239.361ms



  ๐ŸŒˆ SUMMARY RESULTS ๐ŸŒˆ


Suites:   1 passed, 1 of 1 completed
Asserts:  1 passed, of 1
Time:   415.463ms
----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files |       0 |        0 |       0 |       0 |
----------|---------|----------|---------|---------|-------------------
$ npm i -g faucet
$ node test.js | faucet

(node:84914) ExperimentalWarning: The test runner is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
โœ“ true is not false
# tests 1
# pass 1
โœ“ skipped 0
โœ“ todo 0
โœ“ duration_ms 0.076367098

You can read the documentation to learn more

Binaries!

Users can now build Node.js with custom V8 startup snapshots, to increase performance.

In layman's terms, this means that you can cache some dependencies in the node.js source code itself, to improve startup time.

$ cd /where/is/node/source/code
$ ./configure --node-snapshot-main=marked.js # where marked.js is the source of the marked library
$ make node
// your-program.js
// globalThis.marked is now deserialized from the snapshot
// so node.js doesnt need to parse it again
// which improves startup time
const marked = globalThis.marked;
marked(/* ... */);
$ out/Release/node your-program.js

Node.js is working on JS APIs for this, which means that we can essentially build Node.js apps as distributable binaries!


Node.js v18 has some really exciting new features. I've been waiting forever for the fetch API to land and I've always wished Node.js had binaries. The testing framework is also neat!

ย