{"id":10404,"library":"node-fetch","title":"Node-Fetch","description":"Node-Fetch brings the Web Fetch API to Node.js, providing a familiar interface for making HTTP requests in a Node.js environment. The current stable version is 3.3.2. Both the v3 (ESM-only) and v2 (CommonJS) branches are actively maintained, receiving regular bug fixes and occasional new features.","status":"active","version":"3.3.2","language":"javascript","source_language":"en","source_url":"https://github.com/node-fetch/node-fetch","tags":["javascript","fetch","http","promise","request","curl","wget","xhr","whatwg","typescript"],"install":[{"cmd":"npm install node-fetch","lang":"bash","label":"npm"},{"cmd":"yarn add node-fetch","lang":"bash","label":"yarn"},{"cmd":"pnpm add node-fetch","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Node-Fetch v3 is ESM-only and requires import syntax. For v2, use require.","wrong":"const fetch = require('node-fetch');","symbol":"fetch","correct":"import fetch from 'node-fetch';"},{"symbol":"Headers","correct":"import { Headers } from 'node-fetch';"},{"symbol":"Request","correct":"import { Request } from 'node-fetch';"},{"symbol":"Response","correct":"import { Response } from 'node-fetch';"},{"symbol":"AbortController","correct":"import { AbortController } from 'node-fetch';"},{"symbol":"AbortError","correct":"import { AbortError } from 'node-fetch';"}],"quickstart":{"code":"import fetch from 'node-fetch';\n\nasync function getTodoItem() {\n  try {\n    const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');\n\n    if (!response.ok) {\n      throw new Error(`HTTP error! status: ${response.status}`);\n    }\n\n    const data = await response.json();\n    console.log('Fetched TODO item:', data);\n  } catch (error) {\n    console.error('Error fetching data:', error);\n  }\n}\n\ngetTodoItem();","lang":"typescript","description":"This example demonstrates how to make a basic GET request to an external API and parse the JSON response. It also includes error handling for network issues and non-OK HTTP statuses."},"warnings":[{"fix":"Use `import fetch from 'node-fetch';` in an ESM context (e.g., in a `.mjs` file or a project with `\"type\": \"module\"` in `package.json`). For CommonJS, use `const fetch = await import('node-fetch');` (dynamic import) or stick to `node-fetch@2.x`.","message":"Node-Fetch v3 is an ECMAScript Module (ESM) and does not support CommonJS `require()` syntax directly. If you are in a CommonJS project, you must use dynamic `import()` or revert to `node-fetch` v2.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"After awaiting `fetch`, always check `if (!response.ok) { throw new Error(...) }` before trying to read the body.","message":"Unlike some HTTP clients, `node-fetch` does not automatically throw an error for non-successful HTTP status codes (e.g., 404, 500). You must explicitly check `response.ok` or `response.status`.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Store the result of `response.json()` or `response.text()` in a variable if you need to access the body content multiple times, or use `response.clone()` before consuming it.","message":"The `Response` body is a stream and can only be consumed once. Attempting to call methods like `response.json()`, `response.text()`, or `response.blob()` multiple times will result in an error.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Use an `AbortController` to implement request timeouts. Create a controller, set a timeout, and pass the `signal` to the fetch options: `fetch(url, { signal: controller.signal })`.","message":"`node-fetch` (mimicking the browser Fetch API) does not have a built-in timeout option for requests. Long-running requests can hang indefinitely.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Ensure your project's Node.js version is `16.0.0` or higher. Update your `package.json`'s `engines` field accordingly.","message":"Node-Fetch v3 officially requires Node.js v16 or greater for full support. Using it on older Node.js versions might lead to unexpected issues, despite what older `engines` fields might imply.","severity":"gotcha","affected_versions":">=3.0.0"}],"env_vars":null,"last_verified":"2026-04-18T00:00:00.000Z","next_check":"2026-07-17T00:00:00.000Z","problems":[{"fix":"Change `const fetch = require('node-fetch');` to `import fetch from 'node-fetch';`. Ensure your `package.json` has `\"type\": \"module\"` or use `.mjs` file extension.","cause":"Attempting to use `require('node-fetch')` in a project configured for ECMAScript Modules (ESM) or a `.mjs` file when using Node-Fetch v3.","error":"ReferenceError: require is not defined"},{"fix":"Provide a full, absolute URL (e.g., `https://example.com/api/data`) or construct one using `new URL(relativePath, baseUrl)` before passing it to `fetch`.","cause":"Passing a relative URL (e.g., `/api/data`) to `fetch` without providing a base URL or being in a browser-like environment.","error":"TypeError: Only absolute URLs are supported"},{"fix":"Verify that the target server is running and accessible at the specified URL and port. Check firewall rules or proxy settings if applicable.","cause":"The server or resource you are trying to reach is not running, is inaccessible, or is blocking the connection.","error":"FetchError: request to http://localhost:3000/api/data failed, reason: connect ECONNREFUSED 127.0.0.1:3000"},{"fix":"Store the result of the first body consumption (e.g., `const data = await response.json();`) into a variable. If you need to read the body in multiple formats or multiple times, use `const clonedResponse = response.clone();` before the first consumption.","cause":"Attempting to call `response.json()`, `response.text()`, `response.blob()`, etc., more than once on the same `Response` object.","error":"TypeError: Response body stream already consumed"},{"fix":"This is often an expected error for timeouts. Catch `AbortError` specifically (e.g., `if (error instanceof AbortError) { console.log('Request timed out'); }`) to handle it gracefully without crashing your application.","cause":"A `fetch` request was cancelled using an `AbortController`'s `signal.abort()` method, often due to a configured timeout or explicit cancellation.","error":"FetchError: AbortError: The user aborted a request."}],"ecosystem":"npm"}