Isomorphic Fetch API
Isomorphic Unfetch is a lightweight JavaScript library that provides a universal `fetch` API implementation, automatically switching between `unfetch` (a minimal `fetch` ponyfill for browsers) and `node-fetch` (a `fetch` implementation for Node.js) based on the execution environment. The current stable version is 5.0.0. This package aims for a small footprint and consistent behavior across client-side and server-side JavaScript, abstracting away environment-specific `fetch` implementations. It provides both a ponyfill (default named import) and a global polyfill (side-effect import). Recent major updates include the adoption of `node-fetch` v3.x, which mandates Node.js >= 12.20.0, and the addition of first-class TypeScript definitions and Package Exports for improved module resolution. It focuses on simplicity and compatibility with standard `fetch` API usage.
Common errors
-
ERR_REQUIRE_ESM
cause Attempting to `require()` `isomorphic-unfetch` in a Node.js environment with an older version of Node.js (prior to 12.20.0) or when `node-fetch` 3.x's ESM nature causes conflicts with CJS contexts.fixUpgrade Node.js to version 12.20.0 or newer. If still encountering issues, ensure your project is configured for ESM (e.g., `"type": "module"` in `package.json`) or use dynamic `import('isomorphic-unfetch')`. -
ReferenceError: fetch is not defined
cause Using `isomorphic-unfetch` version 4.0.0 or later as a ponyfill without explicitly assigning the imported `fetch` function or importing the polyfill entry point.fixEither import the `fetch` function explicitly (e.g., `import fetch from 'isomorphic-unfetch';`) and use it, or import the polyfill for global availability (`import 'isomorphic-unfetch/polyfill';`). -
TypeError: response.json is not a function
cause Misunderstanding that `response.json()` returns a Promise, not the parsed JSON directly, or issues with an invalid response body not being parsable as JSON.fixAlways `await` `response.json()` or use `.then()` on it, for example: `const data = await response.json();`. Ensure the server response actually contains valid JSON.
Warnings
- breaking Starting with `isomorphic-unfetch@4.0.1`, the underlying `node-fetch` dependency was upgraded to v3.x. This version of `node-fetch` is ESM-only and requires Node.js version >= 12.20.0. Applications running on older Node.js versions will encounter errors.
- breaking In `unfetch@4.0.0` (which `isomorphic-unfetch` bundles), the default `import fetch from 'unfetch'` (or `isomorphic-unfetch`) changed from being a global polyfill to a ponyfill. This means `fetch` is no longer automatically installed on `window` or `global` unless explicitly imported via the polyfill entry point.
- breaking Version 5.0.0 introduced Package Exports for better module resolution, and officially added TypeScript definitions. While improving compatibility, this might affect custom build configurations or tools that do not fully support `exports` maps in `package.json`.
- gotcha A security fix for `node-fetch` was included in `isomorphic-unfetch@3.1.0`. While specific details are not provided in the changelog, it is generally recommended to upgrade to this version or newer to incorporate any critical security patches.
- gotcha Prior to `unfetch@4.2.0`, `.json()` parse errors would throw synchronously. After this version, they return a rejected Promise, aligning with standard `fetch` behavior.
Install
-
npm install isomorphic-unfetch -
yarn add isomorphic-unfetch -
pnpm add isomorphic-unfetch
Imports
- fetch
const fetch = require('isomorphic-unfetch');import fetch from "isomorphic-unfetch";
- (polyfill)
import fetch from 'isomorphic-unfetch'; // expecting global fetch
import 'isomorphic-unfetch/polyfill';
- fetch (types)
import type { Request, Response, Headers } from 'isomorphic-unfetch';
Quickstart
import fetch from "isomorphic-unfetch";
import type { RequestInit, Response } from 'isomorphic-unfetch';
interface Post {
userId: number;
id: number;
title: string;
body: string;
}
async function getExamplePosts(postId: number = 1): Promise<Post | Post[]> {
// Use a public API for demonstration
const url = `https://jsonplaceholder.typicode.com/posts/${postId}`;
const options: RequestInit = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
// body: JSON.stringify({ key: 'value' }) // Example for POST/PUT
};
try {
const response: Response = await fetch(url, options);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
console.log(`Fetched post(s) from ${url}:`, data);
return data;
} catch (error) {
console.error("Error fetching data:", error);
throw error;
}
}
// Example usage
getExamplePosts(1)
.then(() => getExamplePosts(2))
.then(() => getExamplePosts()) // Fetch all posts example, though API usually limits
.catch(err => console.error("An error occurred during quickstart execution:", err));
// Optional: Global polyfill usage example if you need `fetch` on global scope:
// import 'isomorphic-unfetch/polyfill';
// // Now `fetch` is globally available for other parts of your app
// // For example, `globalThis.fetch` or `window.fetch`