@whatwg-node/fetch
0.12.1 · 30 Sep 2026MIT8.9M / weekRepositoryHomepagenpmAtom feed
92 stable releases, newest first, by release line. Notes are quoted as the maintainers published them.
- 0.12.x · latest line
0.12.1
30 Sep 2026#3642
ed29dc2Thanks @ardatan! - Follow the Fetch standard when the Node HTTP transport follows redirects.fetchNodeHttprecursed on every 3xxLocationwhileredirectwas'follow'(the default) and never counted hops. A response that always redirects could keep onefetchcall issuing requests until the process ran out of memory. Following now stops after 20 redirects. The promise rejects withTypeError: Fetch failed: Maximum number of redirects (20) reachedandcodeTooManyRedirects. A chain of 20 redirects that then returns a normal response still completes.That path also reused the previous request's
Headersobject for the next hop. A cross-originLocationtherefore receivedAuthorization,Proxy-Authorization,Cookie,Cookie2, and an explicitHost. Those headers are removed when the origin changes. The scheme is part of the origin, so anhttpstohttpredirect drops them too. Same-origin redirects still send them. Removal happens on a new header list, so the caller's ownHeadersobject is left unchanged.301and302responses toPOST, and303responses to any method other thanGETorHEAD, are resent asGETwith no body. The request-body headers go with the body:Content-Encoding,Content-Language,Content-Location,Content-Type, andContent-Length.307and308keep the method and body when that body can be sent again. A one-shot stream cannot, and that redirect rejects.A cross-origin redirect whose URL includes a username or password is rejected with
TypeErrorwhen the request mode iscors. Following it would send those URL credentials to the new origin asAuthorization.A resent
FormDatabody is encoded again with a new multipart boundary of the same length, so itsContent-Lengthstays valid.Content-Typeis replaced because that header names the boundary.redirect: 'error'rejects with aTypeError. A redirect whose target scheme is nothttporhttpsalso rejects with aTypeError.redirect: 'manual'still returns the redirect response.Response.redirect()serializes an absolute URL into theLocationheader and throwsTypeErrorwhen that URL cannot be parsed. A relative URL is stored as given, soResponse.redirect('/')setsLocationto/. The status must be301,302,303,307, or308; any other status throwsRangeError. The response status text is empty.@whatwg-node/fetchuses this transport on Node, so the same limits apply there.
Patch Changes
#3642
ed29dc2Thanks @ardatan! - Follow the Fetch standard when the Node HTTP transport follows redirects.fetchNodeHttprecursed on every 3xxLocationwhileredirectwas'follow'(the default) and never counted hops. A response that always redirects could keep onefetchcall issuing requests until the process ran out of memory. Following now stops after 20 redirects. The promise rejects withTypeError: Fetch failed: Maximum number of redirects (20) reachedandcodeTooManyRedirects. A chain of 20 redirects that then returns a normal response still completes.That path also reused the previous request's
Headersobject for the next hop. A cross-originLocationtherefore receivedAuthorization,Proxy-Authorization,Cookie,Cookie2, and an explicitHost. Those headers are removed when the origin changes. The scheme is part of the origin, so anhttpstohttpredirect drops them too. Same-origin redirects still send them. Removal happens on a new header list, so the caller's ownHeadersobject is left unchanged.301and302responses toPOST, and303responses to any method other thanGETorHEAD, are resent asGETwith no body. The request-body headers go with the body:Content-Encoding,Content-Language,Content-Location,Content-Type, andContent-Length.307and308keep the method and body when that body can be sent again. A one-shot stream cannot, and that redirect rejects.A cross-origin redirect whose URL includes a username or password is rejected with
TypeErrorwhen the request mode iscors. Following it would send those URL credentials to the new origin asAuthorization.A resent
FormDatabody is encoded again with a new multipart boundary of the same length, so itsContent-Lengthstays valid.Content-Typeis replaced because that header names the boundary.redirect: 'error'rejects with aTypeError. A redirect whose target scheme is nothttporhttpsalso rejects with aTypeError.redirect: 'manual'still returns the redirect response.Response.redirect()serializes an absolute URL into theLocationheader and throwsTypeErrorwhen that URL cannot be parsed. A relative URL is stored as given, soResponse.redirect('/')setsLocationto/. The status must be301,302,303,307, or308; any other status throwsRangeError. The response status text is empty.@whatwg-node/fetchuses this transport on Node, so the same limits apply there.
0.12.0
21 Sep 2026#3617
f78c03bThanks @ardatan! - Stop exportingcryptofrom@whatwg-node/fetch(and fromcreateFetch/FetchAPI). UseglobalThis.cryptoinstead; it is available on all supported runtimes (Node.js >=22.15).
- 0.11.x
0.11.0
21 Sep 20260.x packages: minor bump (breaking changes are allowed in minors while major is 0).
1.x packages (
@whatwg-node/promise-helpers,@whatwg-node/server-plugin-cookies): major bump, since dropping supported Node versions is a breaking engines change for SemVer>=1.0.0consumers.
Minor Changes
#3561
52a5bf6Thanks @ardatan! - Drop support for Node.js 18 and 20. The minimum supported Node.js version is now 22.15.
Why
Node.js 18 and 20 are end-of-life and no longer receive security updates. Keeping them in our support matrix forced version-specific workarounds and slowed adoption of newer Node TLS APIs.
The floor is set to 22.15 (not just 22.0) so we can rely on
tls.getCACertificates()(Node.js 22.15 / 23.10) and always-onzlibzstd helpers (createZstdCompress/createZstdDecompress, Node.js 22.15 / 23.8). That matches the oldest currently supported LTS line (22 Maintenance) while dropping only EOL majors.SemVer
0.x packages: minor bump (breaking changes are allowed in minors while major is 0).
1.x packages (
@whatwg-node/promise-helpers,@whatwg-node/server-plugin-cookies): major bump, since dropping supported Node versions is a breaking engines change for SemVer>=1.0.0consumers.
What changed
engines.node: all published packages now declare>=22.15.0(including@whatwg-node/promise-helpers, which was still on>=16).@whatwg-node/events: removed. NativeCustomEvent/Event/EventTargetare available on Node.js 22+, so the ponyfill is no longer maintained; use the platform globals.@whatwg-node/fetch: dropped therequire("crypto").webcryptofallback;cryptois alwaysglobalThis.cryptoon supported runtimes.@whatwg-node/server: removed the Node 18setHeadersworkaround (isNode1x);ServerResponse#setHeadersis used whenever it exists.@whatwg-node/node-fetch: Runtime guards forzlib.createZstdCompress/createZstdDecompressare removed;zstdis always included inAccept-Encoding.CI / e2e: unit matrix is
[22, 24, 26]; AWS Lambda runtime and Azure Function target moved from Node 20 to Node 22.
If you are still on Node 18 or 20, upgrade to Node.js 22.15+ (or 24 / 26) before installing this release.
#3604
b726b83Thanks @ardatan! - Drop the optionalnode-libcurldependency.The ponyfill HTTP transport now always uses
node:http/node:https. ThefetchCurlcode path and theglobalThis.libcurlruntime check have been removed.HTTP/2 support that previously came from
node-libcurlis no longer available in this release; a follow-up adds optional undici-based transport (including HTTP/2).If you were relying on
node-libcurlbeing picked up automatically, the ponyfill will now use the built-in Node.js HTTP stack instead.
- 0.10.x
0.10.13
10 Nov 2025Reading the note…
0.10.12
4 Nov 2025Reading the note…
0.10.11
19 Sep 2025Reading the note…
0.10.10
1 Aug 2025Reading the note…
0.10.9
17 Jul 2025Reading the note…
0.10.8
20 May 2025Reading the note…
0.10.7
10 May 2025Reading the note…
0.10.6
14 Apr 2025Reading the note…
0.10.5
24 Feb 2025Reading the note…
0.10.4
20 Feb 2025Reading the note…
0.10.3
10 Jan 2025Reading the note…
0.10.2
10 Jan 2025Reading the note…
0.10.1
9 Nov 2024Reading the note…
0.10.0
8 Nov 2024Reading the note…
- 0.9.x
0.9.23
4 Nov 2024Reading the note…
0.9.22
21 Oct 2024Reading the note…
0.9.21
21 Aug 2024Reading the note…
0.9.20
14 Aug 2024Reading the note…
0.9.19
26 Jul 2024Reading the note…
0.9.18
1 Jun 2024Reading the note…
0.9.17
1 Mar 2024Reading the note…
0.9.16
25 Jan 2024Reading the note…
0.9.15
2 Jan 2024Reading the note…
0.9.14
25 Oct 2023Reading the note…
0.9.13
11 Sep 2023Reading the note…
0.9.12
1 Sep 2023Reading the note…
0.9.11
1 Sep 2023Reading the note…
0.9.10
1 Sep 2023Reading the note…
0.9.9
14 Jul 2023Reading the note…
0.9.8
10 Jul 2023Reading the note…
0.9.7
22 Jun 2023Reading the note…
0.9.6
13 Jun 2023Reading the note…
0.9.5
13 Jun 2023Reading the note…
0.9.4
8 Jun 2023Reading the note…
0.9.3
5 Jun 2023Reading the note…
0.9.2
2 Jun 2023Reading the note…
0.9.1
31 May 2023Reading the note…
0.9.0
17 May 2023Reading the note…
- 0.8.x
0.8.8
24 Apr 2023Reading the note…
0.8.7
24 Apr 2023Reading the note…
0.8.6
23 Apr 2023Reading the note…
0.8.5
17 Apr 2023Reading the note…
0.8.4
23 Mar 2023Reading the note…
0.8.3
20 Mar 2023Reading the note…
0.8.2
3 Mar 2023Reading the note…
0.8.1
10 Feb 2023Reading the note…
0.8.0
10 Feb 2023Reading the note…