isomorphic-fetch is effectively unmaintained — its latest release, 3.0.0, shipped in 2020 — and any project still installing it should plan a migration rather than an upgrade. The package solved a real problem in the mid-2010s: one fetch call that worked in both Node.js and the browser. That problem no longer exists for modern runtimes, and an idle dependency in the HTTP path is a poor place to accept staleness. This review covers what isomorphic-fetch actually contains, where its risk comes from, and the cleanest exits.
A quick anatomy
Like other universal-fetch shims, isomorphic-fetch writes no HTTP logic itself. It wires together two dependencies:
- Node.js: delegates to
node-fetch(declared as a 2.x range). - Browser: loads the
whatwg-fetchpolyfill and relies on the global it creates.
One behavioral quirk distinguishes it from cross-fetch: isomorphic fetch installs its polyfill globally, mutating the environment for everything else in the process, whereas cross-fetch offers a non-polluting import. Global mutation from a dependency is exactly the kind of side effect that makes test environments and other libraries behave unpredictably.
Maintenance status: the core finding
The facts on the npm isomorphic-fetch listing are unambiguous:
- Latest version: 3.0.0, published in 2020.
- No releases, and minimal repository activity, in the five years since.
- Still used by roughly 6,500+ dependent packages on the registry.
That combination — frozen upstream, huge dependent base — is the classic shape of ecosystem drag. Nobody is triaging issues against modern Node versions, nobody is updating dependency ranges, and if a vulnerability were found in the wrapper itself, there is no evidence a patch would ship promptly. "No known CVEs against the wrapper" is true, but it is a weak comfort when the wrapper is one thin file over a client that has had CVEs.
Where the actual risk lives: the node-fetch chain
Because the server path is node-fetch 2.x, isomorphic-fetch users inherit that client's advisory history:
- CVE-2022-0235 — node-fetch forwarded
authorization,cookie, and other secure headers to a different origin when following redirects. Fixed in node-fetch 2.6.7. Rated high severity. - CVE-2020-15168 — the
sizelimit was not enforced after redirects, allowing oversized responses to slip through. Fixed in node-fetch 2.6.1.
isomorphic-fetch 3.0.0 declares node-fetch with a caret range, so a fresh npm install today resolves a patched 2.6.x/2.7.x release. The danger is historical lockfiles: a project that generated its lockfile in 2021 may still pin node-fetch 2.6.1–2.6.6 and be silently vulnerable to the header leak while package.json looks perfectly reasonable. Full detail on those advisories is in our node-fetch vulnerability guide.
Check the resolved reality, not the declared range:
npm ls node-fetch
npm audit --omit=dev
This resolved-versus-declared gap is the single most common false-clean result in manual dependency review, and it is why lockfile-aware software composition analysis matters. A scanner such as Safeguard reads the lockfile pin, maps it against the advisory database, and flags the vulnerable resolution even when the manifest range would permit a safe one.
Modern alternatives, ranked
1. Native fetch (best for applications). Node 18+ ships a global fetch built on undici; browsers have had it for a decade. If your support matrix is Node 18 and evergreen browsers, the correct number of fetch polyfills is zero. Remove isomorphic-fetch and the node-fetch and whatwg-fetch subtrees leave your dependency graph entirely.
2. cross-fetch (for libraries with older support matrices). Maintained, small, and offers a non-global import. Pin at 3.1.5 or later — see our cross-fetch security review for its own advisory history.
3. undici directly (for server-heavy workloads). If you only run in Node and want connection pooling, per-origin agents, and interceptors, undici's own API gives you more control than any fetch shim.
Migration in practice
For most codebases this is a one-hour change, not a project:
// before
import 'isomorphic-fetch'; // global polyfill side effect
const res = await fetch(url);
// after (Node 18+ / modern browsers)
const res = await fetch(url); // just delete the import
Then:
npm uninstall isomorphic-fetch
npm ls node-fetch whatwg-fetch # confirm the subtrees are gone
Watch for three behavioral differences when the server side moves from node-fetch to undici-backed native fetch:
agentoptions are replaced by undicidispatcherconfiguration.- Timeout handling moves to
AbortSignal.timeout(ms). - Some error classes change (
FetchErrordisappears), so broadcatchblocks should assert on behavior, not class names.
If isomorphic-fetch arrives transitively through an SDK you cannot edit, use your package manager's override mechanism (overrides in npm, resolutions in yarn) to force the node-fetch resolution to a patched version while you pressure the upstream to modernize.
The general lesson: polyfills should have expiry dates
Every environment shim is a bet that the platform gap it papers over will persist. When the platform catches up — as it did when fetch went native in Node — the shim flips from asset to liability: it keeps old transport code alive in your process, adds packages to every audit, and inflates your SBOM with names your scanner has to track forever. A quarterly "polyfill review" that asks what platform gap does this still cover? is a cheap habit that steadily shrinks attack surface. isomorphic-fetch is one of the clearest cases in the npm ecosystem where the answer is now "none."
FAQ
Is isomorphic-fetch deprecated?
It is not formally marked deprecated on npm, but its latest release shipped in 2020 and the repository has seen essentially no maintenance since. Functionally, you should treat it as end-of-life and migrate.
Does isomorphic-fetch have known vulnerabilities?
No CVE has been published against the wrapper itself. Its practical risk is transitive: the Node path uses node-fetch 2.x, which has had real advisories (CVE-2022-0235, CVE-2020-15168). Old lockfiles can pin vulnerable node-fetch versions even though the declared range allows patched ones.
What should I replace isomorphic-fetch with?
For applications on Node 18+, native fetch — delete the import and the dependency. For libraries that must support older Node and browsers, cross-fetch (3.1.5+) is the maintained equivalent. For server-only performance work, use undici directly.
How do I know if my lockfile has a vulnerable node-fetch pin?
Run npm ls node-fetch to see the resolved version and npm audit to check it against advisories. Anything below 2.6.7 on the 2.x line should be regenerated or overridden.