xh: An HTTPie-Compatible HTTP Client Built for Speed in Rust
Project brief: Friendly and fast tool for sending HTTP requests. Usage Run xh help or man xh for more detailed information.
At a glance
- What is it?
- xh is a Rust reimplementation of HTTPie's command-line interface, promising faster performance while keeping the same request-item syntax. This review covers its installation, usage, compatibility mode, and limitations.
- Who is it for?
- Adopt xh if you are an HTTPie user who wants a faster, single-binary alternative with the same request-item syntax and broad package availability. Avoid it if you depend on HTTPie features you have not confirmed in xh's own help (`xh help` or `man xh`).
- Can I use it commercially?
- Yes. MIT 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 8 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 November 14, 2026, and from our analysis. They are not legal advice.
Star history
- ducaale/xh8,188 ★ · +195
| Repository | 2026-08-04 | 2026-11-14 |
|---|---|---|
| ducaale/xh | 8k | 8.2k |
195 Stars in the last 102 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
What xh Solves and Who It Targets
The README states that xh reimplements as much as possible of HTTPie's design with a focus on improved performance. It targets developers and operators who already know HTTPie's request-item syntax and want a drop-in replacement that feels identical but runs faster. The project is written in Rust, which suggests a compiled binary with low startup overhead. It is not for people who want a graphical tool or a full-featured API client; it is strictly a command-line utility.
How the Request-Item Syntax Works
The core mechanism is the request-item syntax inherited from HTTPie. You pass key-value pairs after the URL, and xh interprets them based on their separators. For example, `name=ahmed` sets a string field, while `age:=24` sets a numeric JSON value. Query strings use `==`, so `id==5` appends `id=5` to the URL. Headers are set with a colon, as in `x-api-key:12345`, and a trailing colon removes a header. Semicolons add headers with empty values. This syntax is compact and expressive, letting you build requests without writing verbose flags. The README also mentions nested JSON construction using a JSON path as a key, like `app[container][0][id]=090-5`, which is useful for complex payloads.
Installation and Package Availability
Getting xh running is straightforward. The README lists a cURL script for Linux and macOS, a PowerShell script for Windows, and a long table of package managers. You can install via Cargo with `cargo install xh --locked`, but you need Rust 1.85 or later. For Debian and Ubuntu, it is available via apt since Debian 13 and Ubuntu 25.04, but those builds use native-tls only, which may affect TLS support. Arch, Fedora, FreeBSD, NetBSD, and many others have packages. Windows users can use Scoop, Chocolatey, or Winget. This wide distribution makes adoption easy if you already use a supported package manager. The pre-built binaries on the release page are another option, but the README does not detail how to verify their integrity.
URL Shorthands and Scheme Handling
xh includes several URL conveniences. You can omit the scheme, so `xh example.com` resolves to `http://example.com`. A leading colon is shorthand for localhost, making `:3000/users` equivalent to `localhost:3000/users`. A leading `://` converts a URL into a valid command, which is handy when copying from a browser. For HTTPS by default, you can invoke the binary as `xhs` or set the binary name to `https` or `xhttps`. This is a clever trick: the behavior depends on argv[0], so you create a symlink like `ln -s ./xh ./xhs`. This avoids adding a flag for a common need. However, it means the default scheme is HTTP unless you remember to use the symlink, which could lead to unintended plaintext requests if you forget.
Compatibility Mode and Its Limits
xh offers a strict compatibility mode with HTTPie. If you rename the binary to `http` or `https`, or set the `XH_HTTPIE_COMPAT_MODE` environment variable, it runs in that mode. The README says the only current difference is that `--check-status` is not enabled by default. The wording implies that outside compatibility mode xh enables `--check-status` by default, so exit codes for error responses can differ between the two modes. The README does not mention other differences, but it also says 'as much as possible,' implying there may be gaps.
Limitations and When It Is the Wrong Tool
The README reveals a few limitations. First, the Alpine, Debian and Ubuntu packages are built with native-tls only. Second, the compatibility mode is not complete; the README says 'only current difference,' but future HTTPie features may not be mirrored. Third, the request-item syntax is powerful but can become unwieldy for very complex requests, especially nested JSON with many fields. In those cases, a full API client or a scripting language with an HTTP library might be clearer. For the full list of options, the README points to `xh help` or `man xh`.
Maintenance and License Considerations
The repository shows active maintenance. The last push was on 2026-10-29, and the latest release is v0.26.3 from 2026-10-21. Releases are frequent, with v0.26.2 in July 2026 and v0.26.1 in June 2026. This suggests a project that is actively developed and responsive to issues. The license is MIT, which is permissive and allows commercial use, modification, and distribution with attribution. There are no obvious copyleft obligations. For maintenance cost, the project is a single binary, so upgrading is usually a matter of replacing the executable or using your package manager. However, because the project tracks HTTPie's design, you may need to watch for upstream changes that affect compatibility.
Editorial conclusion
Adopt xh if you are an HTTPie user who wants a faster, single-binary alternative with the same request-item syntax and broad package availability. Avoid it if you depend on HTTPie features you have not confirmed in xh's own help (`xh help` or `man xh`). Before switching, verify that your workflow does not rely on HTTPie-specific features absent from xh, and test the --check-status behavior, which differs in compatibility mode. The project is actively maintained, with recent releases in 2026, so check the changelog for the latest compatibility details.
Frequently asked questions
How do I install xh?
On Linux and macOS the script route is `curl -sfL https://raw.githubusercontent.com/ducaale/xh/master/install.sh | sh`, and on Windows it is the PowerShell equivalent. There are nineteen package manager rows, from `brew install xh` to `winget add ducaale.xh`, and prebuilt binaries for Linux, macOS and Windows on the release page. Building with cargo install xh --locked needs Rust 1.85 or later.
How do I make xh use HTTPS by default?
Name the binary one of xhs, https or xhttps. Package manager installs should provide both xh and xhs, and if not you create the alias yourself with `cd /path/to/xh && ln -s ./xh ./xhs`, after which xh resolves http URLs and xhs resolves https ones.
How do I send a JSON request body with xh?
With request items: `=` sets a string field and `:=` sets any other JSON type, so `xh httpbin.org/post name=ahmed age:=24` posts an object. Nested keys use JSON path, as in `app[container][0][id]=090-5`, and the body can also be read from standard input or from a file with @filename.
How does xh compare with HTTPie?
It reimplements as much as possible of HTTPie's design with a focus on improved performance, and it uses HTTPie's request-item syntax directly. In compatibility mode, entered by renaming the binary to http or https or by setting XH_HTTPIE_COMPAT_MODE, the only current difference from HTTPie is that --check-status is not enabled by default.
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/ducaale-xh)Star history chart for your README
[](https://hysenlabs.com/projects/ducaale-xh)Was this useful?