cross-fetch

Universal WHATWG Fetch API ponyfill for Node, browsers, and React Native

Library
npm
v4.1.0
1,694 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
43 /100 Fair
Development Activity 0
Maintenance 20
Community 52
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
70 /100 Good
Architecture 68
Code Quality 72
Innovation 55
Learning Curve 85

cross-fetch provides a single fetch implementation that behaves consistently across Node.js, browsers, and React Native, so libraries and applications can call the WHATWG Fetch API without branching on runtime environment. It resolves to node-fetch under Node, the browser’s native fetch in browsers, and a React Native-compatible implementation on that platform, all behind one import.

The package ships both as a ponyfill (cross-fetch, the default import — does not touch global state) and as a polyfill (cross-fetch/polyfill, which assigns fetch/Headers/Request/Response onto globalThis for code that expects fetch to already exist globally). It also normalizes schemaless URLs (//example.com/path) to https:// on the server for parity with browser behavior.

What You Get

  • A single fetch import that resolves to the correct implementation per environment (Node via node-fetch, browser native, React Native-specific build) via package.json’s browser/react-native/main fields
  • A ponyfill entry point (cross-fetch) that does not mutate global scope, for libraries that want an explicit import
  • A polyfill entry point (cross-fetch/polyfill) that assigns fetch/Headers/Request/Response onto the global object for code expecting ambient fetch
  • Schemaless URL normalization (//host/path -> https://host/path) on the Node side for browser-like behavior parity
  • Bundled TypeScript type definitions (index.d.ts)

Common Use Cases

  • Isomorphic/universal JavaScript libraries and SDKs that must run identically in Node and the browser without environment-specific fetch code
  • Server-side rendering (Next.js, Remix, etc.) codebases that share data-fetching logic between server and client bundles
  • Test suites and Node scripts that need a spec-compliant fetch before Node’s own native fetch was universally available
  • React Native apps that want the same fetch-based data layer code as their web counterpart

Under The Hood

Architecture - The package’s package.json routes to different entry files per consumer via the main (dist/node-ponyfill.js), browser (dist/browser-ponyfill.js), and react-native (dist/react-native-ponyfill.js) fields, letting bundlers and Node’s own resolution algorithm pick the right implementation automatically. The Node ponyfill (src/node-ponyfill.js) is a thin wrapper around node-fetch that additionally rewrites schemeless URLs to https:// before delegating, and re-exports Headers/Request/Response from the same underlying package. The separate polyfill/ subpackage and cross-fetch/polyfill entry point (src/node-polyfill.js) layer global assignment on top of the ponyfill only when global.fetch isn’t already defined, keeping the two usage modes cleanly separated.

Tech Stack - Plain JavaScript (CommonJS) with a single runtime dependency on node-fetch for the Node path; built with Rollup and esbuild plugins into per-target bundles, tested with Mocha/Chai (plus mocha-headless-chrome for real-browser test runs) and nock for HTTP mocking, with standard for linting.

Code Quality - Over 40 files under test/, organized by concern (test/fetch-api, test/module-system, test/setup), including a headless-Chrome run to validate actual browser behavior rather than only a jsdom approximation — a meaningfully more rigorous approach for a cross-environment compatibility shim. SECURITY.md documents a responsible-disclosure process, and Husky/commitlint enforce conventional commits, though the project’s own commit velocity has slowed since Node adopted native fetch.

API Design - The package deliberately mirrors the standard fetch(url, options) signature and Web-standard Headers/Request/Response classes exactly, so switching between cross-fetch and a native fetch requires no code changes — the entire value proposition is being invisible at the call site while resolving correctly per platform.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers