cURLParse cURL Converter

HTTP Clients in 2026: The Packages That Grew Most Are Not Maintained

cURLParse — Convert cURL Commands to Python, Node.js, Go & Rust Guides · Updated 2026-10-12 · All guides

Every "state of HTTP clients" post asks which library is good. That question is already answered and nobody installs on the answer. This page looks at a different instrument: the npm downloads API, which counts what build machines actually installed. Window is 2024-10-01 to 2026-10-10, pulled 2026-10-12; "first" is the first 30 days, "last" the final 30. Swap the package name at the end of that URL to check any figure — I would rather be checked than trusted.

Install counts, not people, and not choices: a package pulled transitively is credited as loudly as one someone picked on purpose. That distinction is the entire finding here.

The table

PackageFirst 30 daysLast 30 daysChangeLast publish
undici57.22M889.6M+15.5×2026-09-24
node-fetch243.4M913.2M+275%2023-07-25
formdata-node13.52M74.04M+448%2023-10-24
ky8.161M30.53M+274%2026-10-09
cross-fetch69.94M172.7M+147%2024-12-21
superagent41.83M104.2M+149%2026-09-23
isomorphic-fetch22.44M49.99M+123%2020-09-23
axios234.6M527.4M+125%2026-08-26
got90.25M186.5M+107%2026-08-30

Last-publish dates read from the registry on 2026-10-12, not remembered.

Four of the five fastest growers are fossils

Rank the table by growth, set aside undici for the reason below, and look at what is left:

  • formdata-node — +448%, last released 2023-10-24. A FormData polyfill for Node, a job Node has done natively for years.
  • node-fetch — +275%, last released July 2023. A fetch polyfill.
  • ky — +274%, last released 2026-10-09. The exception: real, maintained, chosen.
  • cross-fetch — +147%, last released December 2024.
  • isomorphic-fetch — +123%, last released September 2020 — untouched in six years.

Four of those are compatibility shims. They exist so that code written against window.fetch or a browser FormData keeps working on an older runtime. Nobody chose them in 2026; something above them did, years ago, and that something is still being installed millions of times a month. A shim's growth curve is a fossil record of the dependency graph above it — it measures how much old software is still being built, not what anyone would pick today.

The corollary is uncomfortable for anyone reading install counts as a popularity signal: node-fetch finished the window at 913.2M installs in 30 days, ahead of undici's 889.6M. The unmaintained polyfill out-installs the thing that replaced it.

The one number that means something

undici at +15.5× is the only row here where growth and maintenance point the same way, and it is growing for a reason that has nothing to do with anyone adopting it. Node ships fetch built on undici. Measured on this machine, Node v24.21.0:

typeof fetch            // 'function'  — global, no install
require('undici')       // MODULE_NOT_FOUND — not on disk: it is inside the binary

So every install of every modern Node app drags undici's implementation along inside the runtime, and the downloads that move that number belong to Node's own distribution surface rather than to a choice made in a package.json. That is worth stating plainly, because +15.5× is the largest number in the table and it is the least attributable to preference.

got (+107%) and axios (+125%) are the slowest rows, and both are actively maintained. axios is still the most-installed chosen client on this list by a wide margin at 527.4M — it is what most 2019-era tutorials still tell you to install, so a lot of that number is inheritance.

What this cannot show you

  • Transitive from direct. This API will not break the two apart, and for polyfills the ratio is the whole story. My guess is node-fetch is overwhelmingly transitive; I cannot prove it with this instrument, so I am writing it as a guess.
  • Browser usage at all. Bundles do not appear in npm downloads. Axios in a React app shipped to a CDN is invisible here.
  • Which HTTP client your code should use. Nothing in this table measures throughput, connection reuse, timeouts, or how a library handles a half-closed socket.

Where curl still sits

None of the above changes the fact that the most portable HTTP interface is still a command line: curl is on every machine you will ever debug on, needs no dependency graph, and its invocation is legible to a colleague who did not write it. It is also why a tool like this one exists — the curl command is the format people paste at each other, in issues, in docs, and increasingly in generated output. If you want the flags that actually change behaviour rather than the ones that look important, that is the flags that matter, and quoting is its own trap: quoting hell.

Decisions this does and does not settle

  • Do not install a fetch polyfill for Node ≥ 18. fetch is a global (measured above). A shim here buys you a dependency and a deprecation risk in exchange for nothing.
  • Do not read any row as "this is the best client." Read undici as "Node's default HTTP is now the default HTTP," and read node-fetch as "a lot of software has not been touched since 2022."
  • If you are choosing today: undici when you want connection pooling, interceptors, or a mock agent and are Node-only; ky if you want the spec's ergonomics with retries and are fine being browser-shaped; axios if you need the same code to run unchanged in a browser and a Node process. All three are maintained as of the dates above — re-check them, they age.

Figures are 30-day windows from the npm API as pulled 2026-10-12; the window slides, so re-pull anything load-bearing. October 2026 is partial in monthly pulls and dips accordingly, which is why the table uses 30-day windows instead.

Developer Sponsor / Partner
Copied to clipboard!