reqwest: the batteries-included Rust HTTP client, and where it stops
An easy and powerful Rust HTTP Client
At a glance
- What is it?
- reqwest wraps hyper in a higher-level client with async and blocking APIs, JSON, multipart, cookies and WASM support. It is the default reach for most Rust services, but the feature flags and the TLS choice decide how much you actually compile.
- Who is it for?
- Adopt reqwest when you want one HTTP client across async services, blocking scripts and WASM builds, and you are willing to manage Cargo feature flags. Do not adopt it if you need an HTTP server (axum is the server side of this stack) or if you want a synchronous-only client with no Tokio dependency, where ureq is the smaller answer.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem reqwest solves for Rust services
Raw hyper gives you an HTTP state machine: connections, protocol versions, body streams. That is the right level for a proxy or a custom server, and the wrong level for a service that just needs to call three APIs and parse JSON. reqwest sits above hyper and provides a Client with a request builder, response decoding, redirect policy, proxies, a cookie store and optional compression. The Cargo.toml describes it as a "higher level HTTP client library", which is the accurate framing: it is a convenience layer, not a protocol implementation.
The audience is Rust application developers. The README lists async and blocking clients, plain bodies, JSON, urlencoded and multipart bodies, customizable redirect policy, HTTP proxies, HTTPS via rustls or system-native TLS, a cookie store and WASM. A CLI tool that fetches a URL and a high-throughput service that fans out to internal APIs both fit, but they will not enable the same features. That is the first decision reqwest forces on you.
How reqwest is put together: features, TLS and the client object
The public surface is a Client plus a RequestBuilder. You construct a client, build a request from it, send it, and get a Response whose body you decode. The interesting part is under the feature flags in Cargo.toml, because reqwest ships almost everything as opt-in.
The default feature set is default-tls, charset, http2 and system-proxy. default-tls maps to rustls, so a plain dependency pulls in rustls and rustls-platform-verifier rather than OpenSSL. http2 pulls in h2 and the hyper http2 features. The README states that when the native-tls feature is enabled, reqwest uses the operating system TLS framework where available, meaning Windows and macOS; on Linux it uses the available OpenSSL or fails to build if it is not found. The native-tls-vendored feature compiles a copy of OpenSSL instead. That is a real build-time constraint, not a footnote: switching to native-tls changes what your build machine needs.
Other flags are independent: blocking, cookies, gzip, brotli, zstd, charset, multipart, json. Each one adds dependencies. The repository also carries examples for the less common paths, including examples/h3_simple.rs, examples/tor_socks.rs and examples/connect_via_lower_priority_tokio_runtime.rs, so the repository layout shows the intended extension points rather than leaving them to the docs alone.
Installing reqwest and making a first request
reqwest is published on crates.io, so installation means adding it to Cargo.toml. The Cargo.toml sets rust-version to 1.85.0, so an older toolchain will fail before it compiles anything. The README's example enables the json feature and Tokio:
[dependencies]
reqwest = { version = "0.13", features = ["json"] }
tokio = { version = "1", features = ["full"] }With those dependencies in place, the README's async example fetches a URL and deserializes the body into a HashMap. Note that it uses the free function reqwest::get rather than a Client, and it is marked no_run in the README because it performs network I/O:
use std::collections::HashMap;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::get("https://httpbin.org/ip")
.await?
.json::<HashMap<String, String>>()
.await?;
println!("{resp:#?}");
Ok(())
}Running that prints the parsed JSON body as a debug-formatted map. The free function is fine for a script. For anything that sends more than one request, build a Client once and reuse it, because the client owns the connection pool and the configuration. The repository ships examples/simple.rs, examples/json_typed.rs, examples/json_dynamic.rs and examples/form.rs if you want a starting point closer to your use case than the README snippet.
Where reqwest is the wrong choice
The blocking feature is a wrapper, not a second implementation. The Cargo.toml shows it pulling in futures-channel, futures-util and tokio/sync, which means the blocking client still drags Tokio into your dependency graph. If your project is deliberately synchronous and you want no async runtime at all, this is the wrong tool, and the repository does not offer a runtime-free mode.
The TLS story is the second constraint. The default rustls path avoids OpenSSL, which is usually what you want for cross-compilation and static binaries. But it also means you are not using the system trust store through the OS framework by default, and the README is explicit that native-tls on Linux needs OpenSSL present or the build fails. Teams that switch to native-tls for corporate certificate stores inherit that build requirement. The README does not document a rollback path for that decision; you change the feature flags and rebuild.
Finally, reqwest is a client only. If your problem is accepting HTTP requests, this is not the library you want, and the search interest in reqwest versus axum mostly reflects that confusion. axum is a server framework; reqwest calls servers.
reqwest against hyper, ureq and curl
The comparison that matters is with hyper, because reqwest is built on it. hyper is the protocol layer: you assemble connections and services yourself, and you get control over exactly how requests are dispatched. reqwest trades that control for a request builder, redirect handling, proxies, cookies and body decoding. If you are writing a library that must not impose an async runtime or a TLS choice on its users, hyper is the safer dependency. If you are writing an application, reqwest removes a large amount of boilerplate.
ureq is the synchronous alternative. It targets the case reqwest's blocking feature only approximates: a client with no async runtime underneath. That is a cleaner fit for a small CLI or a build script. The trade-off is the ecosystem around async, HTTP/2 and the connection pooling that comes with the Tokio stack.
curl is a different category entirely. It is a binary and a C library, useful for shell scripts and for reproducing a request outside your program. It is not a substitute for an in-process client, and the README does not position reqwest as one. The practical split is that curl proves a request works, and reqwest is what you ship.
Maintenance, licensing and upgrade cost
The repository is not archived, and the last push was on 2026-09-17. Releases are frequent: v0.13.3 on 2026-04-27, v0.13.4 on 2026-05-25 and v0.13.5 on 2026-09-08. The CHANGELOG.md at the repository root is where those changes are recorded, and it is the file to read before bumping the version in Cargo.toml.
Upgrade cost is dominated by feature flags rather than API churn. Because TLS, HTTP/2, compression and cookies are separate features, a version bump can change which dependencies resolve, and a build that worked with rustls may behave differently if you also enable native-tls. The rust-version field is 1.85.0, so a toolchain upgrade can be a prerequisite for a reqwest upgrade. On the licensing side, Cargo.toml declares MIT OR Apache-2.0, the README repeats that dual licence, and both LICENSE-MIT and LICENSE-APACHE are present at the repository root. The README also states that contributions are dual licensed under the same terms unless stated otherwise. That is the standard Rust arrangement, but it is worth confirming against your own policy rather than assuming it is compatible.
Editorial conclusion
Adopt reqwest when you want one HTTP client across async services, blocking scripts and WASM builds, and you are willing to manage Cargo feature flags. Do not adopt it if you need an HTTP server (axum is the server side of this stack) or if you want a synchronous-only client with no Tokio dependency, where ureq is the smaller answer. Before committing, verify three things in your own build: that your toolchain is at least 1.85.0, that rustls is acceptable for your target hosts, and that the features you enable match the code you actually call.
Frequently asked questions
What is reqwest?
It is a higher-level HTTP client library for Rust, built on hyper. The README describes it as ergonomic and batteries-included, with async and blocking clients, JSON, urlencoded and multipart bodies, redirect policy, proxies, cookies and WASM.
Can reqwest handle cookies?
Yes, through the cookies feature, which the Cargo.toml maps to the cookie_crate and cookie_store dependencies. It is not enabled by default, so you have to add it to your feature list.
Is reqwest asynchronous?
It offers both. The README lists async and blocking Clients, and the example uses an async main with Tokio. The blocking feature is opt-in and, per Cargo.toml, still pulls in Tokio components.
How does reqwest differ from hyper?
reqwest is built on hyper and adds a request builder, redirect handling, proxies, cookies and body decoding on top. hyper is the lower-level protocol layer, which is the better choice when a library must not impose an async runtime or TLS choice on its users.
How does reqwest differ from ureq?
ureq is the synchronous alternative with no async runtime underneath. reqwest's blocking feature is a wrapper that, according to Cargo.toml, still brings in futures-channel, futures-util and tokio/sync, so it is not equivalent to a runtime-free synchronous client.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/seanmonstar-reqwest)