cross-fetch: Universal WHATWG Fetch
cross-fetch provides a universal implementation of the WHATWG Fetch API, making it available consistently across Node.js, modern web browsers, and React Native environments. It currently maintains version 4.1.0 and is actively developed, with frequent patch and minor releases, alongside major version updates to support new Node.js runtimes and integrate updates from its underlying `node-fetch` and `whatwg-fetch` dependencies. Its primary differentiator is simplifying HTTP requests by abstracting away environment-specific `fetch` implementations, allowing developers to write isomorphic code without conditional imports or manual polyfill management. This ensures that `fetch` behaves predictably whether executed server-side or client-side, addressing common challenges in full-stack JavaScript applications.
Common errors
-
TypeError: fetch is not a function
cause Attempting to use `fetch` without proper import or in an environment where `cross-fetch` has not been initialized or globally polyfilled.fixEnsure you are using `import { fetch } from 'cross-fetch';` in ESM or `const { fetch } = require('cross-fetch');` in CJS. Alternatively, for global polyfilling, `import 'cross-fetch/polyfill';` (or `require('cross-fetch/polyfill');`) should be at the entry point of your application. -
TS2307: Cannot find module 'cross-fetch' or its corresponding type declarations.
cause TypeScript compiler cannot locate the type definitions for `cross-fetch`.fixEnsure `cross-fetch` is installed correctly. If using an older TypeScript version or specific configuration, verify `tsconfig.json` includes `node_modules/@types` in `typeRoots` and `cross-fetch` is not excluded. Types are shipped with the package itself, so `@types/cross-fetch` is not typically needed. -
Property 'json' does not exist on type 'Response'.
cause This error typically indicates an issue with TypeScript's understanding of the `Response` object, often related to global `lib.dom.d.ts` conflicting or not being properly augmented by `cross-fetch`'s types, especially in earlier versions.fixUpgrade `cross-fetch` to the latest version (e.g., v3.1.2+ addressed similar issues). Ensure your `tsconfig.json` includes `lib` entries appropriate for `dom` if in a browser-like environment, and `esnext`.
Warnings
- breaking cross-fetch v4.0.0 dropped official support for Node.js versions 10 and 12. While it might still function, tests are no longer run against these versions, and no support is provided for issues arising on them.
- gotcha Minor versions of cross-fetch (e.g., v3.2.0, v4.1.0) frequently update their underlying `node-fetch` and `whatwg-fetch` dependencies. This can introduce subtle behavioral changes or new features/bugs inherited from these upstream libraries, which might not be explicitly detailed in `cross-fetch` release notes.
- gotcha The v4.0.0 release noted potential 'implementation conflicts in the Fetch API tests'. While `cross-fetch` aims for WHATWG spec compliance, differences between `node-fetch` and `whatwg-fetch` or their specific versions could lead to edge-case behavioral discrepancies.
Install
-
npm install cross-fetch -
yarn add cross-fetch -
pnpm add cross-fetch
Imports
- fetch
import fetch from 'cross-fetch'; // Named import is preferred as of v3+ const fetch = require('cross-fetch'); // This works, but prefer destructuringimport { fetch } from 'cross-fetch'; - Headers
const Headers = require('cross-fetch').Headers;import { Headers } from 'cross-fetch'; - Request
import { fetch, Request } from 'cross-fetch/dist/node-ponyfill'; // Incorrect path, direct from 'cross-fetch' is universalimport { Request } from 'cross-fetch'; - Response
import { Response } from 'node-fetch'; // If explicitly trying to use the underlying Node.js implementation without cross-fetch's universal layer.import { Response } from 'cross-fetch';
Quickstart
import { fetch } from 'cross-fetch';
async function fetchData() {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log('Fetched data:', data);
// Example with POST request
const postResponse = await fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
title: 'foo',
body: 'bar',
userId: 1,
}),
});
if (!postResponse.ok) {
throw new Error(`HTTP error! status: ${postResponse.status}`);
}
const postData = await postResponse.json();
console.log('Posted data:', postData);
} catch (error) {
console.error('Error fetching data:', error);
}
}
fetchData();