or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-whatwg-fetch

A window.fetch polyfill for browsers that don't natively support the Fetch API

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/whatwg-fetch@3.6.x

To install, run

npx @tessl/cli install tessl/npm-whatwg-fetch@3.6.0

index.mddocs/

whatwg-fetch

whatwg-fetch is a comprehensive polyfill implementation of the Fetch API for web browsers that don't natively support window.fetch. It provides a Promise-based mechanism for making HTTP requests as a modern replacement for XMLHttpRequest, following the WHATWG Fetch specification standards.

Package Information

  • Package Name: whatwg-fetch
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install whatwg-fetch

Core Imports

import 'whatwg-fetch'

// Global polyfill - automatically installs window.fetch and related APIs
// Only installs when native fetch is not available
window.fetch(...)

For explicit access to polyfill components:

import { fetch as fetchPolyfill, Headers, Request, Response, DOMException } from 'whatwg-fetch'

// Use polyfill explicitly alongside or instead of native
fetchPolyfill(...) // Always uses polyfill implementation
window.fetch(...)   // Uses native browser version when available

CommonJS:

require('whatwg-fetch');

// Global polyfill - automatically installs global.fetch, Headers, Request, Response
// Only installs when native fetch is not available
fetch(...)

Basic Usage

import 'whatwg-fetch'

// Simple GET request
fetch('/api/users')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Request failed:', error));

// POST with JSON data
fetch('/api/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'John Doe',
    email: 'john@example.com'
  })
})
  .then(response => response.json())
  .then(data => console.log('User created:', data));

// File upload with FormData
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('description', 'Profile photo');

fetch('/upload', {
  method: 'POST',
  body: formData
})
  .then(response => response.json());

Architecture

whatwg-fetch implements the complete Fetch API specification with these core components:

  • Fetch Function: Main entry point for HTTP requests with Promise-based interface
  • Request Class: HTTP request representation with full configuration support
  • Response Class: HTTP response representation with body parsing methods
  • Headers Class: HTTP headers management with case-insensitive operations
  • Body Interface: Shared body reading methods for Request and Response
  • Global Polyfill: Automatic installation when native fetch is unavailable

Capabilities

HTTP Requests

Core fetch functionality for making HTTP requests with full Promise support.

/**
 * Make an HTTP request
 * @param input - URL string, URL object, or Request object
 * @param init - Optional request configuration
 * @returns Promise that resolves to Response object
 */
function fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;

// Polyfill identification property
fetch.polyfill: boolean;

type RequestInfo = Request | string;

interface RequestInit {
  method?: string;
  headers?: HeadersInit;
  body?: BodyInit;
  credentials?: 'omit' | 'same-origin' | 'include';
  mode?: string;
  referrer?: string;
  signal?: AbortSignal;
}

type ModeType = string;

type BodyInit = string | URLSearchParams | FormData | Blob | ArrayBuffer | ArrayBufferView | null;
type HeadersInit = Headers | Record<string, string> | [string, string][];

Usage Examples:

// GET request
fetch('/api/data')
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response.json();
  });

// POST request with credentials
fetch('/api/login', {
  method: 'POST',
  credentials: 'include',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ username, password })
});

// Request with abort signal
const controller = new AbortController();
fetch('/api/data', {
  signal: controller.signal
});

// Cancel the request
controller.abort();

Request Construction

Create and configure HTTP requests with full type safety and validation.

/**
 * Create a new Request object
 * @param input - URL string, URL object, or existing Request
 * @param options - Request configuration options
 */
class Request {
  constructor(input: RequestInfo, options?: RequestInit);
  
  // Properties
  readonly url: string;
  readonly method: string;
  readonly headers: Headers;
  readonly credentials: 'omit' | 'same-origin' | 'include';
  readonly mode: ModeType;
  readonly signal: AbortSignal;
  readonly referrer: string;
  readonly bodyUsed: boolean;
  
  // Methods
  clone(): Request;
  arrayBuffer(): Promise<ArrayBuffer>;
  blob(): Promise<Blob>;
  formData(): Promise<FormData>;
  json(): Promise<any>;
  text(): Promise<string>;
}

Usage Examples:

// Create request with configuration
const request = new Request('/api/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer token123'
  },
  body: JSON.stringify({ name: 'Alice' })
});

// Clone request for retry logic
const originalRequest = new Request('/api/data', { method: 'GET' });
const retryRequest = originalRequest.clone();

// Read request body
const requestData = await request.json();

Response Handling

Handle HTTP responses with comprehensive body parsing and metadata access.

/**
 * HTTP Response representation
 * @param bodyInit - Response body content
 * @param options - Response configuration
 */
class Response {
  constructor(bodyInit?: BodyInit, options?: ResponseInit);
  
  // Properties
  readonly url: string;
  readonly status: number;
  readonly statusText: string;
  readonly ok: boolean;
  readonly headers: Headers;
  readonly type: 'default' | 'error';
  readonly bodyUsed: boolean;
  
  // Methods
  clone(): Response;
  arrayBuffer(): Promise<ArrayBuffer>;
  blob(): Promise<Blob>;
  formData(): Promise<FormData>;
  json(): Promise<any>;
  text(): Promise<string>;
  
  // Static methods
  static error(): Response;
  static redirect(url: string, status?: number): Response;
}

interface ResponseInit {
  status?: number;
  statusText?: string;
  headers?: HeadersInit;
  url?: string;
}

Usage Examples:

// Handle response with status checking
fetch('/api/data')
  .then(response => {
    console.log(`Status: ${response.status} ${response.statusText}`);
    console.log(`Content-Type: ${response.headers.get('Content-Type')}`);
    
    if (response.ok) {
      return response.json();
    } else {
      throw new Error(`Request failed: ${response.status}`);
    }
  });

// Create custom responses
const successResponse = new Response(
  JSON.stringify({ message: 'Success' }),
  {
    status: 200,
    statusText: 'OK',
    headers: { 'Content-Type': 'application/json' }
  }
);

const errorResponse = Response.error();
const redirectResponse = Response.redirect('/login', 302);

Headers Management

Manage HTTP headers with case-insensitive operations and iteration support.

/**
 * HTTP headers collection
 * @param init - Initial headers as object, array, or Headers instance
 */
class Headers {
  constructor(init?: HeadersInit);
  
  // Methods
  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(callback: (value: string, name: string, headers: Headers) => void, thisArg?: any): void;
  
  // Iterator methods
  keys(): IterableIterator<string>;
  values(): IterableIterator<string>;
  entries(): IterableIterator<[string, string]>;
  [Symbol.iterator](): IterableIterator<[string, string]>;
}

Usage Examples:

// Create headers from object
const headers = new Headers({
  'Content-Type': 'application/json',
  'Authorization': 'Bearer token123'
});

// Add headers
headers.append('X-Custom-Header', 'value1');
headers.append('X-Custom-Header', 'value2'); // Combines: "value1, value2"

// Check and get headers
if (headers.has('Content-Type')) {
  console.log(headers.get('Content-Type')); // "application/json"
}

// Iterate over headers
headers.forEach((value, name) => {
  console.log(`${name}: ${value}`);
});

// Use with fetch
fetch('/api/data', {
  headers: new Headers({
    'Accept': 'application/json',
    'X-API-Key': 'key123'
  })
});

Error Handling

Handle fetch errors and request abortion with standard exception types.

/**
 * DOM Exception for fetch errors
 * @param message - Error message
 * @param name - Exception name (e.g., 'AbortError')
 */
class DOMException extends Error {
  constructor(message?: string, name?: string);
  
  readonly name: string;
  readonly message: string;
  readonly stack: string;
}

Usage Examples:

// Handle different error types
const controller = new AbortController();

fetch('/api/data', { signal: controller.signal })
  .then(response => response.json())
  .catch(error => {
    if (error.name === 'AbortError') {
      console.log('Request was aborted');
    } else if (error instanceof TypeError) {
      console.log('Network error or request failed');
    } else {
      console.log('Other error:', error.message);
    }
  });

// Abort after timeout
setTimeout(() => controller.abort(), 5000);

// Check if polyfill is active
if (fetch.polyfill) {
  console.log('Using whatwg-fetch polyfill');
} else {
  console.log('Using native fetch implementation');
}

// Custom error handling for HTTP errors
function checkStatus(response) {
  if (response.status >= 200 && response.status < 300) {
    return response;
  } else {
    const error = new Error(response.statusText);
    error.response = response;
    throw error;
  }
}

fetch('/api/data')
  .then(checkStatus)
  .then(response => response.json());

Browser Compatibility

  • Chrome: All versions
  • Firefox: All versions
  • Safari: 6.1+
  • Internet Explorer: 10+
  • Modern Browsers: Use native fetch when available

The polyfill automatically detects native fetch support and only installs itself when needed.

Important Notes

  • Promise Rejection: fetch() only rejects on network errors, not HTTP error status codes (404, 500, etc.)
  • Credentials: Use credentials: 'same-origin' for maximum compatibility with cookies
  • CORS: Cross-origin requests require proper server-side CORS configuration
  • Node.js: This polyfill is browser-only and does not work in Node.js environments
  • AbortController: Requires separate polyfill for browsers without native AbortController support
  • Polyfill Detection: Check fetch.polyfill property to determine if polyfill is active
  • Automatic Installation: The polyfill automatically detects native support and only activates when needed
  • Global Scope: Importing the module automatically installs fetch, Headers, Request, Response globally
  • No-Cache Headers: GET/HEAD requests with cache: 'no-store' or cache: 'no-cache' get timestamp parameters added
  • File Protocol: Local file:// URLs receive status 200 even when xhr.status is outside normal range