HTTP Client Maintenance Data: curl, axios, requests, got, undici, HTTPie, httpx
Every "curl vs a code client" comparison argues about ergonomics. None of them note that the question is usually settled by a package manager, not by taste — and that the answer drifts by weeks while you are not looking. This page is the boring measurement instead: who is still shipping, at what rate, and what your machine is actually running.
How this was pulled
curl -s https://api.github.com/repos/curl/curl \
-H "Accept: application/vnd.github+json" # stargazers_count, pushed_at, open_issues_count
curl -s https://api.github.com/repos/curl/curl/releases?per_page=6
curl --version
Pulled 2026-10-12. Numbers change daily; the URLs do not.
The field
| Repo | Stars | Last push | Open issues | Licence |
|---|---|---|---|---|
axios/axios | 109,362 | 2026-10-09 | 108 | MIT |
psf/requests | 54,590 | 2026-09-28 | 244 | Apache-2.0 |
curl/curl | 43,175 | 2026-10-12 | 79 | custom (MIT-like) |
httpie/cli | 38,753 | 2024-12-17 | 348 | BSD-3-Clause |
encode/httpx | 15,620 | 2026-10-02 | 140 | BSD-3-Clause |
sindresorhus/got | 14,946 | 2026-09-20 | 2 | MIT |
nodejs/undici | 7,707 | 2026-10-12 | 375 | MIT |
Three things in this table are not what the star ordering suggests.
httpie/cli has not been pushed since 2024-12-17 — about 22 months, against 38,753 stars and 348 open issues. It is the fourth most-starred thing here and the only one that has stopped. If you have http in a CI image, that is the fact to act on, not the syntax comparison.
got has 2 open issues on 14,946 stars. Read that as triage discipline, not as an absence of bugs: two issues open means issues get closed. Compare undici at 375 and requests at 244, both of which are actively maintained — open-issue count is only meaningful next to push recency, never alone.
undici has 7,707 stars and is the most-used thing on the list, because Node's global fetch is built on it. You are depending on it whether or not you installed it. Star count is a measure of popularity among people who chose to look; it is a poor measure of blast radius.
curl's actual release cadence
Feature releases, from the GitHub release feed:
| Release | Date | Days since previous |
|---|---|---|
| curl 8.17.0 | 2025-11-05 | — |
| curl 8.18.0 | 2026-01-07 | 63 |
| curl 8.19.0 | 2026-03-11 | 63 |
| curl 8.20.0 | 2026-04-29 | 49 |
| curl 8.21.0 | 2026-06-24 | 56 |
| curl 8.22.0 | 2026-09-02 | 70 |
Mean: 60 days between feature releases, remarkably regular, with security patches landing off-cycle in between. So "how stale is my curl" is a calculable quantity, not a vibe.
What this box is running
curl 8.5.0 (aarch64-unknown-linux-gnu) libcurl/8.5.0
Release-Date: 2023-12-06, security patched: 8.5.0-2ubuntu10.15
Latest is 8.22.0 (2026-09-02). That is:
- 1,001 days since this build's upstream release date
- 17 feature releases behind
- distribution-patched (
8.5.0-2ubuntu10.15), so CVEs are being backported — it is not unpatched, it is ancient in version and current in security, which is exactly the state that makes version-based reasoning useless
This is the number I would actually check. A blog post that says "curl added flag X in 8.13" is describing a flag that does not exist on this machine, and -v will not tell you why your command works on a colleague's laptop and returns a parse error here.
curl --version | head -1 # your version
Then compare against <https://curl.se/download.html> or the release feed above. If the gap is more than about ten releases, assume any flag from a recent blog post is unavailable and check curl --help | grep <flag> before debugging the request.
What this means for the "paste a curl command" workflow
This site converts a curl command into Python, Node, Go, and Rust. The maintenance data changes the recommendation slightly per target:
| Target | Default to | Because |
|---|---|---|
| Python, new project | httpx | actively pushed (2026-10-02), modern API, HTTP/2 |
| Python, existing codebase | requests | 244 open issues and still pushed 2026-09-28; nothing to migrate |
| Node, new code | built-in fetch / undici | no dependency to maintain; it is already in the runtime |
| Node, interceptors/retries needed | got | 2 open issues, maintained, richest middleware story |
| Anything in CI you control | pinned curl binary or version-pinned client | the 1,001-days-behind problem above is yours to own |
| Interactive debugging | curl | installed everywhere; httpie is not, and is not being updated |
The generated code from the converter is correct against the current library APIs. It cannot know whether the machine running it has an old distribution build of requests pinned by a lockfile, so the version question stays with you.
What this page cannot tell you
pushed_atincludes CI noise and README typos. It proves the repo is alive, not that maintainers are responsive.- Stars are not usage.
undiciproves the inversion directly: fewest stars here, most deployed. open_issues_countconflates bugs, feature requests, and answered questions. Thegotvsundicigap above is process, not quality.- The licence column is GitHub's SPDX classification, and
curl/curlreportsNOASSERTIONbecause its licence is a custom MIT-derived text. That is a metadata artefact, not a licensing problem — readCOPYINGin the repo. - Download counts are missing from this page deliberately. The npm downloads API returned
invalid datefor every range and point format I tried on 2026-10-11 (20260912:20261011, ISO,last-week,last-month), anddownloads/d2404s. I would rather publish a smaller table than a table with numbers I could not reproduce.