Skip to main content

How do you send an HTTP request from Node.js?

1. The modern way - fetch() (Node.js 18+)

Starting with Node.js 18, the standard fetch() is available globally, exactly like in the browser.

javascript
const res = await fetch('https://api.example.com/data', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: 'Tim', age: 30 }), }); const data = await res.json(); console.log(data);

Advantages:

  • works with no extra libraries;
  • returns a Promise;
  • supports async/await;
  • handles GET, POST, PUT, DELETE, PATCH;
  • automatically supports HTTP/HTTPS, a stream body, JSON, and more.

Important: if you're on Node <18, you need to install a package:

javascript
npm install node-fetch

and import it:

javascript
import fetch from 'node-fetch';

2. The low-level way - http.request() / https.request()

If you need more control (headers, streaming, chunk handling), use the built-in node:http or node:https module.

A GET request example:

javascript
import http from 'node:http'; const options = { hostname: 'example.com', path: '/data', method: 'GET', }; const req = http.request(options, (res) => { let body = ''; res.on('data', (chunk) => (body += chunk)); res.on('end', () => console.log('Response:', body)); }); req.on('error', (err) => console.error('Error:', err)); req.end();

A POST request example:

javascript
import https from 'node:https'; const data = JSON.stringify({ name: 'Tim' }); const options = { hostname: 'api.example.com', path: '/users', method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data), }, }; const req = https.request(options, (res) => { let body = ''; res.on('data', (chunk) => (body += chunk)); res.on('end', () => console.log('Response:', body)); }); req.on('error', (err) => console.error(err)); req.write(data); req.end();

Here you manually control everything: headers, body, status code, and you read the response body as a stream.

3. Streaming downloads (via pipeline)

You can use fetch() or http.get() together with streams, for example to download a file without loading it entirely into memory:

javascript
import { createWriteStream } from 'node:fs'; import { pipeline } from 'node:stream/promises'; const res = await fetch('https://example.com/image.jpg'); await pipeline(res.body, createWriteStream('image.jpg')); console.log('File saved');

4. Via third-party libraries (for convenience)

If you need features like interceptors, timeouts, automatic JSON, and retries, use one of the popular libraries:

Axios

javascript
npm install axios
javascript
import axios from 'axios'; const res = await axios.post('https://api.example.com/users', { name: 'Tim' }); console.log(res.data);
  • Automatically serializes JSON
  • Handles errors and statuses easily
  • Supports interceptors, timeouts, cookies, multipart, etc.

Got

javascript
npm install got
javascript
import got from 'got'; const res = await got.post('https://api.example.com/users', { json: { name: 'Tim' }, responseType: 'json', }); console.log(res.body);

5. What to choose

ApproachWhen to use it
fetch()95% of cases, the standard, modern, simple
http.request()When you need full control (headers, sockets, streams)
axios / gotWhen the project is large and needs a convenient API and interceptors
pipeline()For streamed files (uploads, downloads)

6. In short

In Node.js you can send an HTTP request:

  • the modern way: fetch() (built in since Node 18);
  • the low-level way: via http.request() / https.request();
  • the convenient way: via axios or got.

It all depends on whether you want simplicity (fetch) or maximum control (request).

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.