{"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,"search_vec":"'3.3.2':31 'activ':43 'api':11 'branch':41 'bring':7 'bug':47 'commonj':40 'curl':58 'current':27 'environ':25 'esm':36 'esm-on':35 'familiar':16 'featur':52 'fetch':3,6,10,54 'fix':48 'http':20,55 'interfac':17 'javascript':53 'maintain':44 'make':19 'new':51 'node':2,5 'node-fetch':1,4 'node.js':13,24 'occasion':50 'promis':56 'provid':14 'receiv':45 'regular':46 'request':21,57 'stabl':28 'typescript':62 'v2':39 'v3':34 'version':29 'web':9 'wget':59 'whatwg':61 'xhr':60","created_at":"2026-04-18T08:58:38.522061+00:00","updated_at":"2026-04-18T08:58:38.522061+00:00","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","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/node-fetch/node-fetch","docs":null,"changelog":null,"pypi":null,"npm":"https://www.npmjs.com/package/node-fetch","openapi_spec":null,"status_page":null,"smithery":null,"categories":["http-networking"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-17","next_check":"2026-07-17","install_tag":null}}