unfetch

A 500-byte fetch polyfill and isomorphic ponyfill that brings the Fetch API to old browsers and Node.js alike.

Library
npm
v1.0.3
5,699stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
44/100Fair
Development Activity0
Maintenance20
Community56
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
63/100Good
Architecture75
Code Quality82
Innovation50
Learning Curve45

unfetch is a bare-minimum implementation of the Fetch API, weighing in at roughly 500 bytes gzipped. It wraps XMLHttpRequest to expose a fetch()-shaped function that resolves to a response object supporting text(), json(), blob(), clone(), and a minimal Map-like headers object, covering the subset of the spec most applications actually use rather than the full standard.

The isomorphic-unfetch workspace package published alongside it in the same repository resolves this fetch implementation across environments: in the browser it defers to native window.fetch when present and falls back to unfetch otherwise, while in Node.js it dispatches to node-fetch instead. @plasmicapp/isomorphic-unfetch is a scoped npm publish of that isomorphic entry point, giving consumers the same environment-aware fetch dispatch under the Plasmic org’s own package name.

What You Get

  • A roughly 500-byte browser fetch implementation (unfetch) covering GET/POST, headers, and JSON/text/blob responses
  • An isomorphic entry point that automatically selects native fetch, unfetch, or node-fetch depending on runtime
  • Two usage modes: install globally as window.fetch (polyfill) or import it as a standalone function that never touches globals (ponyfill)
  • TypeScript type declarations for both the browser and isomorphic entry points
  • Prebuilt CJS, ESM, and UMD bundles produced via microbundle, plus a standalone unpkg-hostable polyfill build

Common Use Cases

  • Legacy browser support: shipping fetch() to IE8+ or other fetch-less browsers without pulling in a full spec-compliant implementation
  • Universal/SSR JavaScript apps: using isomorphic-unfetch so the same fetch() call works in Node during server rendering and in the browser after hydration
  • Bundle-size-sensitive projects: adding basic HTTP requests without the weight of larger fetch implementations
  • CDN-only pages: loading unfetch’s polyfill build directly from unpkg to add fetch support with a single script tag, no bundler required

Under The Hood

Architecture The repository is a small npm workspace split into three single-purpose entry surfaces rather than one monolithic module: src/index.mjs implements the core ~35-line XHR-wrapping fetch ponyfill; polyfill/polyfill.mjs is a side-effecting one-liner that installs that function onto self.fetch only if it’s missing; and the packages/isomorphic-unfetch workspace member adds an environment check (browser.mjs/browser.js test for window.fetch, index.mjs/index.js test for process) to route calls to native fetch, unfetch, or node-fetch. There’s no shared internal state or abstraction layer beyond this — each entry point is a thin, independently importable function, which keeps the blast radius of any change limited to the file that changed.

Tech Stack Plain JavaScript (ES2015 source, transpiled toward ES3-compatible output) with hand-written TypeScript .d.ts declarations for typing consumers, no runtime TS compilation. Builds run through microbundle (Rollup-based) to produce CJS, ESM, and UMD outputs plus the standalone polyfill bundle used by unpkg. node-fetch v3 is the only runtime dependency, pulled in solely by the isomorphic entry for server-side requests. npm workspaces wire the root unfetch package and the isomorphic-unfetch sub-package together for local development and testing.

Code Quality Tests run under Jest with babel-jest, covering the XHR-wrapping core (mocked XMLHttpRequest), the polyfill’s global-installation behavior, and the isomorphic dispatcher’s environment detection — the latter exercised through actual Node vm sandboxes that simulate browser and server globals rather than just mocking imports. A dedicated typescript.test.ts file exercises the type declarations against real usage. ESLint (via eslint-config-developit) lints the source, and GitHub Actions runs build+test on every push/PR alongside a separate compressed-size-regression check, so growth in bundle size is caught in CI rather than after publish.

API Design The public surface is intentionally tiny: one function with a fetch(url, options) signature and a response object exposing just the handful of methods (text, json, blob, clone) and header accessors most call sites actually use, explicitly diverging from full Fetch/Headers spec compliance where that would add weight. The README calls out the two caveats most polyfill users hit in practice — that fetch doesn’t send cookies by default and doesn’t reject on HTTP error statuses — with example code for handling both, which lowers the chance of silent surprises for developers new to the Fetch API’s semantics.

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

Search