CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-cross-fetch

Universal WHATWG Fetch API for Node, Browsers and React Native

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

Cross-Fetch

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.

Package Information

  • Package Name: cross-fetch
  • Package Type: npm
  • Language: JavaScript/TypeScript
  • Installation: npm install cross-fetch

Core Imports

As Ponyfill (Local Import - Recommended)

import 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');

As Polyfill (Global Installation)

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)

CDN Usage

<script src="//unpkg.com/cross-fetch/dist/cross-fetch.js"></script>
<!-- Now fetch is available as window.fetch -->

Basic Usage

Simple GET Request

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);

POST Request with JSON

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();

Using Request and Response Objects

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();

Capabilities

Fetch Function

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.js: Uses node-fetch internally, auto-prefixes schemaless URIs (//api.comhttps://api.com)
  • Browser: Uses native fetch or whatwg-fetch polyfill
  • React Native: Uses global fetch API
  • Workers: Compatible with Service Workers and CloudFlare Workers

Special properties:

  • fetch.ponyfill === true when used as ponyfill
  • fetch.polyfill === true when used as polyfill

Request Constructor

Creates 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>;
}

Response Constructor

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;
}

Headers Constructor

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][];

AbortController Integration

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;
}

Types

Common Types

// 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";

Platform Compatibility

Cross-fetch automatically detects the runtime environment and uses the appropriate implementation:

  • Node.js: Uses node-fetch package with additional schemaless URI support (//example.comhttps://example.com)
  • Browsers: Uses native fetch or falls back to whatwg-fetch polyfill
  • React Native: Uses the built-in global fetch API
  • Web Workers: Compatible with Service Workers and CloudFlare Workers
  • TypeScript: Full type definitions included

Platform-specific Entry Points

The package provides different builds for different environments:

  • Main (Node.js): dist/node-ponyfill.js - Node.js ponyfill using node-fetch
  • Browser: dist/browser-ponyfill.js - Browser ponyfill with whatwg-fetch fallback
  • React Native: dist/react-native-ponyfill.js - React Native using global fetch
  • Polyfill variants: Each platform has corresponding polyfill versions that install globally

Bundle Detection

The appropriate bundle is automatically selected based on your environment and module system, with specific support for:

  • CommonJS modules (require())
  • ES6 modules (import)
  • UMD builds for direct browser usage
  • Webpack and other bundlers

Usage Patterns

Ponyfill vs Polyfill

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 fetch

Key differences:

  • Ponyfill: fetch.ponyfill === true, no global pollution, explicit imports
  • Polyfill: fetch.polyfill === true, global installation, implicit availability

Error Handling

import 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);
}

Timeout and AbortController

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);
  }
}

Install with Tessl CLI

npx tessl i tessl/npm-cross-fetch
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/cross-fetch@4.1.x
Publish Source
CLI
Badge
tessl/npm-cross-fetch badge