Node 18 ((link)) Access

This wasn't just about convenience. It reduced bundle sizes, improved standardization, and made isomorphic JavaScript (code that runs identically on client and server) a true reality. Okay, maybe not death , but a serious challenge. Node 18 introduced an experimental test runner that later became stable in Node 20. For the first time, you could write and run tests without a single devDependency .

// Good import readFile from 'node:fs/promises'; // Bad (in ESM, this might break with bundlers) import readFile from 'fs'; Short answer: No for new projects. Long answer: It depends. node 18

// test/basic.test.js import test from 'node:test'; import assert from 'node:assert'; test('synchronous passing test', (t) => assert.strictEqual(1, 1); ); This wasn't just about convenience

// Before Node 18 (and 17.5 experimental) const fetch = require('node-fetch'); // After Node 18 async function getData() const res = await fetch('https://api.example.com/data'); const data = await res.json(); console.log(data); Node 18 introduced an experimental test runner that

But as of April 2026, Node 18 belongs in the history books—not your production servers. If you haven't migrated to Node 20 (and soon, 22), treat this as your wake-up call.

test('asynchronous passing test', async (t) => assert.strictEqual(await Promise.resolve(2), 2); );

Thank Node 18 for fetch , streams, and a built-in test runner. Then leave it behind. What version of Node are you running in production right now? Let us know in the comments below.