Universal WHATWG Fetch API for Node, Browsers and React Native
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Universal WHATWG Fetch API for Node, Browsers, Workers and React Native. Cross-fetch provides platform-agnostic HTTP request functionality that works seamlessly across different JavaScript runtime environments while adhering to the WHATWG fetch specification for consistent behavior.
npm install cross-fetchimport fetch from 'cross-fetch';For named imports:
import { fetch, Request, Response, Headers } from 'cross-fetch';CommonJS:
const fetch = require('cross-fetch');
// or
const { fetch, Request, Response, Headers } = require('cross-fetch');import 'cross-fetch/polyfill';
// Now fetch is available globally as window.fetch (browser) or global.fetch (Node.js)CommonJS:
require('cross-fetch/polyfill');
// Now fetch is available globally as window.fetch (browser) or global.fetch (Node.js)<script src="//unpkg.com/cross-fetch/dist/cross-fetch.js"></script>
<!-- Now fetch is available as window.fetch -->import fetch from 'cross-fetch';
const response = await fetch('https://api.example.com/data');
if (response.status >= 400) {
throw new Error('Bad response from server');
}
const data = await response.json();
console.log(data);import fetch from 'cross-fetch';
const response = await fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'John Doe',
email: 'john@example.com'
})
});
const result = await response.json();import { fetch, Request, Response, Headers } from 'cross-fetch';
const headers = new Headers({
'Authorization': 'Bearer token123',
'Content-Type': 'application/json'
});
const request = new Request('https://api.example.com/protected', {
method: 'GET',
headers: headers
});
const response = await fetch(request);
const data = await response.text();The main HTTP request function that provides universal fetch API across all platforms.
/**
* Performs HTTP requests following the WHATWG Fetch API specification
* @param input - URL string or Request object
* @param init - Optional request configuration
* @returns Promise that resolves to a Response object
*/
declare function fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
// Type definitions for input and options
type RequestInfo = Request | string;
interface RequestInit {
method?: string;
headers?: HeadersInit;
body?: BodyInit | null;
referrer?: string;
referrerPolicy?: ReferrerPolicy;
mode?: RequestMode;
credentials?: RequestCredentials;
cache?: RequestCache;
redirect?: RequestRedirect;
integrity?: string;
keepalive?: boolean;
signal?: AbortSignal | null;
}Platform-specific behavior:
node-fetch internally, auto-prefixes schemaless URIs (//api.com → https://api.com)Special properties:
fetch.ponyfill === true when used as ponyfillfetch.polyfill === true when used as polyfillCreates Request objects following the WHATWG Request API specification.
/**
* Request constructor for creating HTTP request objects
* @param input - URL string or existing Request object
* @param init - Optional request configuration
*/
declare class Request {
constructor(input: RequestInfo, init?: RequestInit);
readonly method: string;
readonly url: string;
readonly headers: Headers;
readonly destination: RequestDestination;
readonly referrer: string;
readonly referrerPolicy: ReferrerPolicy;
readonly mode: RequestMode;
readonly credentials: RequestCredentials;
readonly cache: RequestCache;
readonly redirect: RequestRedirect;
readonly integrity: string;
readonly keepalive: boolean;
readonly signal: AbortSignal;
clone(): Request;
arrayBuffer(): Promise<ArrayBuffer>;
blob(): Promise<Blob>;
formData(): Promise<FormData>;
json(): Promise<any>;
text(): Promise<string>;
}Creates Response objects following the WHATWG Response API specification.
/**
* Response constructor for creating HTTP response objects
* @param body - Optional response body
* @param init - Optional response configuration
*/
declare class Response {
constructor(body?: BodyInit | null, init?: ResponseInit);
readonly type: ResponseType;
readonly url: string;
readonly redirected: boolean;
readonly status: number;
readonly ok: boolean;
readonly statusText: string;
readonly headers: Headers;
readonly body: ReadableStream<Uint8Array> | null;
readonly bodyUsed: boolean;
static error(): Response;
static redirect(url: string, status?: number): Response;
clone(): Response;
arrayBuffer(): Promise<ArrayBuffer>;
blob(): Promise<Blob>;
formData(): Promise<FormData>;
json(): Promise<any>;
text(): Promise<string>;
}
interface ResponseInit {
status?: number;
statusText?: string;
headers?: HeadersInit;
}Creates Headers objects following the WHATWG Headers API specification.
/**
* Headers constructor for managing HTTP headers
* @param init - Optional initial headers
*/
declare class Headers {
constructor(init?: HeadersInit);
append(name: string, value: string): void;
delete(name: string): void;
get(name: string): string | null;
has(name: string): boolean;
set(name: string, value: string): void;
forEach(callbackfn: (value: string, key: string, parent: Headers) => void, thisArg?: any): void;
entries(): IterableIterator<[string, string]>;
keys(): IterableIterator<string>;
values(): IterableIterator<string>;
[Symbol.iterator](): IterableIterator<[string, string]>;
}
type HeadersInit = Headers | Record<string, string> | [string, string][];Supports request cancellation using the AbortController API for timeout and manual cancellation.
/**
* AbortController integration for request cancellation
* Use the signal property in RequestInit to enable cancellation
*/
interface AbortController {
readonly signal: AbortSignal;
abort(): void;
}
interface AbortSignal {
readonly aborted: boolean;
addEventListener(type: 'abort', listener: () => void): void;
removeEventListener(type: 'abort', listener: () => void): void;
}// Body types that can be sent in requests or responses
type BodyInit = ArrayBuffer | ArrayBufferView | Blob | FormData | ReadableStream<Uint8Array> | URLSearchParams | string;
// Request modes
type RequestMode = "cors" | "no-cors" | "same-origin" | "navigate";
// Credential handling
type RequestCredentials = "omit" | "same-origin" | "include";
// Cache modes
type RequestCache = "default" | "no-store" | "reload" | "no-cache" | "force-cache" | "only-if-cached";
// Redirect handling
type RequestRedirect = "follow" | "error" | "manual";
// Response types
type ResponseType = "basic" | "cors" | "default" | "error" | "opaque" | "opaqueredirect";
// Referrer policies
type ReferrerPolicy = "" | "no-referrer" | "no-referrer-when-downgrade" | "same-origin" | "origin" | "strict-origin" | "origin-when-cross-origin" | "strict-origin-when-cross-origin" | "unsafe-url";
// Request destinations
type RequestDestination = "" | "audio" | "audioworklet" | "document" | "embed" | "font" | "frame" | "iframe" | "image" | "manifest" | "object" | "paintworklet" | "report" | "script" | "serviceworker" | "sharedworker" | "style" | "track" | "video" | "worker" | "xslt";Cross-fetch automatically detects the runtime environment and uses the appropriate implementation:
node-fetch package with additional schemaless URI support (//example.com → https://example.com)fetch or falls back to whatwg-fetch polyfillfetch APIThe package provides different builds for different environments:
dist/node-ponyfill.js - Node.js ponyfill using node-fetchdist/browser-ponyfill.js - Browser ponyfill with whatwg-fetch fallbackdist/react-native-ponyfill.js - React Native using global fetchThe appropriate bundle is automatically selected based on your environment and module system, with specific support for:
require())import)Ponyfill (Recommended): Import locally without modifying global scope. Safer for libraries and applications as it avoids potential conflicts.
import fetch from 'cross-fetch';
// Use fetch function directly - isolated to your module
const response = await fetch('https://api.example.com');Polyfill: Installs globally by modifying the global object. Use when you want drop-in replacement for native fetch.
import 'cross-fetch/polyfill';
// Now window.fetch (browser) or global.fetch (Node.js) is available everywhere
const response = await fetch('https://api.example.com'); // Using global fetchKey differences:
fetch.ponyfill === true, no global pollution, explicit importsfetch.polyfill === true, global installation, implicit availabilityimport fetch from 'cross-fetch';
try {
const response = await fetch('https://api.example.com/data');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
// Process data
} catch (error) {
console.error('Fetch failed:', error);
}import fetch from 'cross-fetch';
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);
try {
const response = await fetch('https://api.example.com/data', {
signal: controller.signal
});
clearTimeout(timeoutId);
const data = await response.json();
// Process data
} catch (error) {
if (error.name === 'AbortError') {
console.log('Request was aborted');
} else {
console.error('Fetch failed:', error);
}
}