How to Use the Node Fetch Module in Node.js
Node.js 18 and later versions ship with a native fetch API implementation based on Undici, enabling standard web-compatible HTTP requests without installing external packages.
The Node fetch module provides a modern, promise-based interface for making HTTP requests in server-side JavaScript. As integrated into the Node.js core runtime, this native API eliminates the dependency on third-party libraries like node-fetch or axios for most network operations.
Enabling Native Fetch
Node.js introduced fetch as an experimental global in version 17.5 and stabilized it in version 18.0. Unlike legacy solutions, you do not need to import or install the node fetch module explicitly—it is available as a global function.
// No import required in Node.js 18+
const response = await fetch('https://api.example.com/data');
const data = await response.json();
For Node.js versions between 17.5 and 18.0, enable the feature using the command-line flag:
node --experimental-fetch app.js
Basic Request Syntax
The fetch() function accepts a URL string and an optional options object, returning a Promise that resolves to a Response object.
// Simple GET request
const response = await fetch('https://api.example.com/users');
// POST request with JSON payload
const postResponse = await fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: 'Alice', role: 'admin' }),
});
Handling Response Objects
Always verify the response status before parsing. The Response object provides several methods to consume the body:
const response = await fetch('https://api.example.com/data');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
// Parse based on content type
const jsonData = await response.json();
const textData = await response.text();
const bufferData = await response.arrayBuffer();
Request Configuration Options
The options object supports standard Web Fetch API parameters:
- method: HTTP method (GET, POST, PUT, DELETE, PATCH)
- headers: Headers instance or plain object with string values
- body: Request body (string, Buffer, Uint8Array, ReadableStream, or null)
- redirect: 'follow' (default), 'error', or 'manual'
- signal: AbortSignal for request cancellation
const response = await fetch('https://api.example.com/upload', {
method: 'PUT',
headers: {
'Authorization': 'Bearer token123',
'Content-Type': 'application/octet-stream',
},
body: Buffer.from('binary data'),
redirect: 'follow',
});
Error Handling and Timeouts
Use AbortController to cancel in-flight requests or implement timeout logic:
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);
try {
const response = await fetch('https://api.example.com/slow', {
signal: controller.signal,
});
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
} catch (error) {
if (error.name === 'AbortError') {
console.log('Request was aborted due to timeout');
} else {
console.error('Network error:', error.message);
}
}
Working with Streams
The native node fetch module supports streaming for large file downloads and uploads:
const response = await fetch('https://example.com/large-file.zip');
// Stream to file
const fs = require('fs');
const stream = fs.createWriteStream('./output.zip');
for await (const chunk of response.body) {
stream.write(chunk);
}
stream.end();
Summary
- The Node fetch module is available globally in Node.js 18+ without requiring imports or installation.
- It implements the standard Web Fetch API specification for consistency with browser environments.
- Use
AbortControllerfor request cancellation and implementing timeout behavior. - Always check
response.okorresponse.statusbefore processing response bodies. - Native fetch supports multiple body types including strings, Buffers, and streams.
Frequently Asked Questions
Do I need to install the node fetch module separately?
No. The native fetch API is built into Node.js core starting with version 18.0.0. For Node.js versions 16.x and 17.x, you could enable it using the --experimental-fetch flag, but production applications should use Node.js 18 or later for stable, unflagged support.
How do I send authentication headers with fetch?
Include an Authorization header in the options object. For Bearer tokens: headers: { 'Authorization': 'Bearer YOUR_TOKEN' }. For basic authentication, encode credentials using Base64: headers: { 'Authorization': 'Basic ' + Buffer.from('user:pass').toString('base64') }.
Can I use fetch with TypeScript?
Yes. Node.js 18+ includes TypeScript definitions for the global fetch function, Request, Response, and Headers interfaces. These types align with the standard DOM lib definitions, providing full IntelliSense and type safety without additional @types packages.
What is the difference between native fetch and the node-fetch npm package?
Native fetch eliminates external dependencies and receives direct performance optimizations through the underlying Undici library. The node-fetch package (version 3.x) is still maintained for legacy Node.js version support or specific non-standard behaviors, but native fetch is recommended for all new projects running Node.js 18+.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s https://instagit.com/install.md