Published at
Updated at
Reading time
2min

Do you know what this code does?

import fetch, { Headers, Request, Response } from 'node-fetch'

if (!global.fetch) {
  const agent = ({ protocol }) =>
    protocol === 'http:' ? global.__NEXT_HTTP_AGENT : global.__NEXT_HTTPS_AGENT
  const fetchWithAgent = (url, opts, ...rest) => {
    if (!opts) {
      opts = { agent }
    } else if (!opts.agent) {
      opts.agent = agent
    }
    return fetch(url, opts, ...rest)
  }
  global.fetch = fetchWithAgent
  global.Headers = Headers
  global.Request = Request
  global.Response = Response
}

The code comes from the Next.js codebase and polyfills the fetch method. It has been an excellent developer experience to not worry about making HTTP requests in Next.js while relying on an API that works in the browser. I got so used to writing fetch code that I almost forgot that the Framework polyfills it on the server-side.

But here's some news!

Node.js 18 comes with global fetch

April 19, Node.js 18 was released, and it includes a fetch method so that fetch polyfills and additional HTTP package become redundant. The new global fetch is based on the undici package.

const res = await fetch('https://nodejs.org/api/documentation.json');
if (res.ok) {
  const data = await res.json();
  console.log(data);
}

Start writing this dependency-free HTTP-based code in Node today. ☝️🎉

But be aware, the feature is still marked as experimental. Maintainer Matteo Collina pointed out that the performance of streams isn't good yet.

This addition is a great step towards real cross-platform JavaScript because the code above runs in the browser and on the server. And with it, the browser globals fetch, FormData, Headers, Request and Response are at your service in Node.js now.

Node.js followed the Deno runtime, which aims to use web platform APIs as much as possible. Competition enables innovation.

Check the release notes for more good stuff like the new native test runner.

import test from 'node:test';

test('top level test', async (t) => {
  await t.test('subtest 1', (t) => {
    assert.strictEqual(1, 1);
  });
});

I can't wait to see where we're heading with these new server APIs!

If you enjoyed this article...

Join 5.5k readers and learn something new every week with Web Weekly.

Web Weekly — Your friendly Web Dev newsletter
Reply to this post and share your thoughts via good old email.
Stefan standing in the park in front of a green background

About Stefan Judis

Frontend nerd with over ten years of experience, freelance dev, "Today I Learned" blogger, conference speaker, and Open Source maintainer.

Related Topics

Related Articles