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.
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:
npm install node-fetchand import it:
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:
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:
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:
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
npm install axiosimport 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
npm install gotimport 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
| Approach | When to use it |
|---|---|
fetch() | 95% of cases, the standard, modern, simple |
http.request() | When you need full control (headers, sockets, streams) |
axios / got | When 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
axiosorgot.It all depends on whether you want simplicity (
fetch) or maximum control (request).
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.