Technical Documentation: ducaale/xh
โน๏ธ Provenance: Multi-Tier Ingestion ยท CodeWiki Reference
Overview (`README.md`)
xh
xh is a friendly and fast tool for sending HTTP requests. It reimplements as much
as possible of HTTPie's excellent design, with a focus
on improved performance.
Installation
via cURL (Linux & macOS)
curl -sfL https://raw.githubusercontent.com/ducaale/xh/master/install.sh | shvia Powershell (Windows)
iwr -useb https://raw.githubusercontent.com/ducaale/xh/master/install.ps1 | iexvia a package manager
| OS | Method | Command |
|---|---|---|
| Any | Cargo* | cargo install xh --locked |
| Any | Huber | huber install xh |
| Any | Mise | mise use xh --global |
| Android (Termux) | pkg | pkg install xh |
| Android (Magisk/KernelSU) | MMRL** | mmrl install xhhttp |
| Alpine Linux | apk*** | apk add xh |
| Arch Linux | Pacman | pacman -S xh |
| Debian & Ubuntu | Apt**** | sudo apt install xh |
| Fedora | Copr***** | sudo dnf install xh |
| FreeBSD | FreshPorts | pkg install xh |
| NetBSD | pkgsrc | pkgin install xh |
| Linux & macOS | Nixpkgs | nix-env -iA nixpkgs.xh |
| Linux & macOS | Flox | flox install xh |
| Linux & macOS | Homebrew | brew install xh |
| Linux & macOS | Hermit | hermit install xh |
| macOS | MacPorts | sudo port install xh |
| Windows | Scoop | scoop install xh |
| Windows | Chocolatey | choco install xh |
| Windows | Winget | winget add ducaale.xh |
* Make sure that you have Rust 1.85 or later installed
** You will need to install the MMRL CLI
*** Built with native-tls only.
**** Available since Debian 13 and Ubuntu 25.04. Built with native-tls only.
***** Enable COPR repo via sudo dnf copr enable ducaale/xh
via pre-built binaries
The release page contains prebuilt binaries for Linux, macOS and Windows.
Usage
/* Detailed source-code truncated for AI context efficiency. */Run xh help or man xh for more detailed information.
Request Items
xh uses HTTPie's request-item syntax to set headers, request body, query string, etc.
=/:=for setting the request body's JSON or form fields (=for strings and:=for other JSON types).==for adding query strings.@for including files in multipart requests e.g[email protected]or[email protected];type=image/jpeg;filename=goodbye.jpg.:for adding or removing headers e.gconnection:keep-aliveorconnection:.;for including headers with empty values e.gheader-without-value;.
An @ prefix can be used to read a value from a file. For example: x-api-key:@api-key.txt.
The request body can also be read from standard input, or from a file using @filename.
To construct a complex JSON object, a JSON path can be used as a key e.g app[container][0][id]=090-5.
For more information on this syntax, refer to https://httpie.io/docs/cli/nested-json.
Shorthand form for URLs
Similar to HTTPie, specifying the scheme portion of the request URL is optional, and a leading colon works as shorthand
for localhost. :8000 is equivalent to localhost:8000, and :/path is equivalent to localhost/path.
URLs can have a leading :// which allows quickly converting a URL into a valid xh or HTTPie command. For examplehttp://httpbin.org/json becomes http ://httpbin.org/json.
xh http://localhost:3000/users # resolves to http://localhost:3000/users
xh localhost:3000/users # resolves to http://localhost:3000/users
xh :3000/users # resolves to http://localhost:3000/users
xh :/users # resolves to http://localhost:80/users
xh example.com # resolves to http://example.com
xh ://example.com # resolves to http://example.comMaking HTTPS requests by default
xh will default to HTTPS scheme if the binary name is one of xhs, https, or xhttps. If you have installed xh
via a package manager, both xh and xhs should be available by default. Otherwise, you need to create one like this:
cd /path/to/xh && ln -s ./xh ./xhs
xh httpbin.org/get # resolves to http://httpbin.org/get
xhs httpbin.org/get # resolves to https://httpbin.org/getStrict compatibility mode
If xh is invoked as http or https (by renaming the binary), or if the XH_HTTPIE_COMPAT_MODE environment variable is set,
it will run in HTTPie compatibility mode. The only current difference is that --check-status is not enabled by default.
Examples
# Send a GET request
xh httpbin.org/json
# Send a POST request with body {"name": "ahmed", "age": 24}
xh httpbin.org/post name=ahmed age:=24
# Send a GET request with querystring id=5&sort=true
xh get httpbin.org/json id==5 sort==true
# Send a GET request and include a header named x-api-key with value 12345
xh get httpbin.org/json x-api-key:12345
# Send a POST request with body read from stdin.
echo "[1, 2, 3]" | xh post httpbin.org/post
# Send a PUT request and pipe the result to less
xh put httpbin.org/put id:=49 age:=25 | less
# Download and save to res.json
xh -d httpbin.org/json -o res.json
# Make a request with a custom user agent
xh httpbin.org/get user-agent:foobarHow xh compares to HTTPie
Advantages
- Improved startup speed.
- Available as a single statically linked binary that's easy to install and carry around.
- HTTP/2 support.
- Builtin translation to curl commands with the
--curlflag. - Short, cheatsheet-style output from
--help. (For longer output, passhelp.)
Disadvantages
- Not all of HTTPie's features are implemented. (#4)
- No plugin system.
- General immaturity. HTTPie is old and well-tested.
- Worse documentation.
Similar or related Projects
- curlie - frontend to cURL that adds the ease of use of httpie
- httpie-go - httpie-like HTTP client written in Go
- curl2httpie - convert command arguments between cURL and HTTPie
Overview (`assets/README.md`)
Syntaxes and themes used
- Sublime-HTTP
- json-kv
- Sublime Packages
- ansi-dark theme
- Solarized and Monokai are based on ansi-dark with color values taken from the pygments library
Tools used to create xh-demo.gif
- asciinema for the initial recording.
- asciinema-edit to speed up the recording.
- asciicast2gif to produce the final GIF. The
default font didn't look great so I modified it to use Cascadia Mono.
Doc Md Template (`doc/md-template.md`)
NAME
xh - Friendly and fast tool for sending HTTP requests
SYNOPSIS
xh [OPTIONS] [METHOD] URL [REQUEST_ITEM ...]DESCRIPTION
xh is an HTTP client with a friendly command line interface. It strives to
have readable output and easy-to-use options.
xh is mostly compatible with HTTPie: see http(1).
The --curl option can be used to print a curl(1) translation of the
command instead of sending a request.
POSITIONAL ARGUMENTS
[METHOD]:
The HTTP method to use for the request.This defaults to GET, or to POST if the request contains a body.
URL:
The URL to request.The URL scheme defaults to
http://normally, orhttps://if
the program is invoked asxhs.A leading colon works as shorthand for localhost.
:8000is equivalent
tolocalhost:8000, and:/pathis equivalent tolocalhost/path.[REQUEST_ITEM ...]:
{{request_items}}
OPTIONS
Each --OPTION can be reset with a --no-OPTION argument.
{{options}}
EXIT STATUS
0: Successful program execution.1: Usage, syntax or network error.2: Request timeout.3: Unexpected HTTP 3xx Redirection.4: HTTP 4xx Client Error.5: HTTP 5xx Server Error.6: Too many redirects.
ENVIRONMENT
XH_CONFIG_DIR:
Specifies where to look for config.json and named session data.
The default is~/.config/xhfor Linux/macOS and%APPDATA%\xhfor Windows.XH_HTTPIE_COMPAT_MODE:
Enables the HTTPie Compatibility Mode. The only current difference is that--check-statusis not enabled by default. An alternative to setting this
environment variable is to rename the binary to either http or https.REQUESTS_CA_BUNDLE,CURL_CA_BUNDLE:
Sets a custom CA bundle path.ALL_PROXY=[protocol://]<host>[:port]:
Sets the proxy server for all requests (unless overridden for a specific protocol).HTTP_PROXY=[protocol://]<host>[:port]:
Sets the proxy server to use for HTTP.HTTPS_PROXY=[protocol://]<host>[:port]:
Sets the proxy server to use for HTTPS.NO_PROXY:
List of comma-separated hosts for which to ignore the other proxy environment variables.*matches all host names.NETRC:
Location of the.netrcfile.NO_COLOR:
Disables output coloring. See https://no-color.orgRUST_LOG:
Configure low-level debug messages. See https://docs.rs/env_logger/0.11.3/env_logger/#enabling-logging
FILES
~/.config/xh/config.json:
xh configuration file. The only configurable option isdefault_options
which is a list of default shell arguments that gets passed toxh.
Example:json{ "default_options": ["--native-tls", "--style=solarized"] }~/.netrc,~/_netrc:
Auto-login information file.~/.config/xh/sessions:
Session data directory grouped by domain and port number.
EXAMPLES
Send a GET request:
xh httpbin.org/jsonSend a POST request with body {"name": "ahmed", "age": 24}:
xh httpbin.org/post name=ahmed age:=24Send a GET request to http://httpbin.org/json?id=5&sort=true:
xh get httpbin.org/json id==5 sort==trueSend a GET request and include a header named X-Api-Key with value 12345:
xh get Ihttpbin.org/json x-api-key:12345Send a POST request with body read from stdin:
echo "[1, 2, 3]" | xh post httpbin.org/postSend a PUT request and pipe the result to less:
xh put httpbin.org/put id:=49 age:=25 | lessDownload and save to res.json:
xh -d httpbin.org/json -o res.jsonMake a request with a custom user agent:
xh httpbin.org/get user-agent:foobarMake an HTTPS request to https://example.com:
xhs example.comREPORTING BUGS
xh's Github issues https://github.com/ducaale/xh/issues
SEE ALSO
curl(1), http(1)
HTTPie's online documentation https://httpie.io/docs/cli
Doc Xh.1 (`doc/xh.1.md`)
NAME
xh - Friendly and fast tool for sending HTTP requests
SYNOPSIS
xh [OPTIONS] [METHOD] URL [REQUEST_ITEM ...]DESCRIPTION
xh is an HTTP client with a friendly command line interface. It strives to
have readable output and easy-to-use options.
xh is mostly compatible with HTTPie: see http(1).
The --curl option can be used to print a curl(1) translation of the
command instead of sending a request.
POSITIONAL ARGUMENTS
[METHOD]:
The HTTP method to use for the request.This defaults to GET, or to POST if the request contains a body.
URL:
The URL to request.The URL scheme defaults to
http://normally, orhttps://if
the program is invoked asxhs.A leading colon works as shorthand for localhost.
:8000is equivalent
tolocalhost:8000, and:/pathis equivalent tolocalhost/path.[REQUEST_ITEM ...]:Optional key-value pairs to be included in the request.
The separator is used to determine the type:
key==value: Add a query string to the URL.key=value: Add a JSON property (--json) or form field (--form) to the request body.key:=value: Add a field with a literal JSON value to the request body.Example:
numbers:=[1,2,3] enabled:=truekey@filename: Upload a file (requires --form or --multipart).To set the filename and mimetype,
;type=and;filename=can be used respectively.Example:
[email protected];type=image/jpeg;filename=profile.jpg@filename: Use a file as the request body.header:value: Add a header, e.g.user-agent:foobarheader:: Unset a header, e.g.connection:header;: Add a header with an empty value.
An
@prefix can be used to read a value from a file. For example:x-api-key:@api-key.txt.A backslash can be used to escape special characters, e.g.
weird\:key=value.To construct a complex JSON object, the REQUEST_ITEM's key can be set to a JSON path instead of a field name. For more information on this syntax, refer to https://httpie.io/docs/cli/nested-json.
OPTIONS
Each --OPTION can be reset with a --no-OPTION argument.
-j,--json: (default) Serialize data items from the command line as a JSON object.Overrides both --form and --multipart.
-f,--form: Serialize data items from the command line as form fields.Overrides both --json and --multipart.
--multipart: Like --form, but force a multipart/form-data request even without files.Overrides both --json and --form.
--raw=RAW: Pass raw request data without extra processing.--pretty=STYLE: Controls output processing. Possible values are:all: (default) Enable both coloring and formattingcolors: Apply syntax highlighting to outputformat: Pretty-print json and sort headersnone: Disable both coloring and formatting
Defaults to
formatif the NO_COLOR env is set and tononeif stdout is not tty.--format-options=FORMAT_OPTIONS: Set output formatting options. Supported option are:json.indent:<NUM>json.format:xml.indent:<NUM>xml.format:headers.sort:
Example: --format-options=json.indent:2,headers.sort:false.
-s,--style=THEME: Output coloring style.[possible values:
auto,solarized,monokai,fruity]--response-charset=ENCODING: Override the response encoding for terminal display purposes.Example: --response-charset=latin1.
--response-mime=MIME_TYPE: Override the response mime type for coloring and formatting for the terminal.Example: --response-mime=application/json.
-p,--print=FORMAT: String specifying what the output should containH: request headersB: request bodyh: response headersb: response bodym: response metadata
Example: --print=Hb.
-h,--headers: Print only the response headers. Shortcut for --print=h.-b,--body: Print only the response body. Shortcut for --print=b.-m,--meta: Print only the response metadata. Shortcut for --print=m.-v,--verbose: Print the whole request as well as the response.Additionally, this enables --all for printing intermediary requests/responses while following redirects.
Using verbose twice i.e. -vv will print the response metadata as well.
Equivalent to --print=HhBb --all.
--debug: Print full error stack traces and debug log messages.Logging can be configured in more detail using the
$RUST_LOGenvironment variable. SetRUST_LOG=traceto show even more messages. See https://docs.rs/env_logger/0.11.3/env_logger/#enabling-logging.--all: Show any intermediary requests/responses while following redirects with --follow.-P,--history-print=FORMAT: The same as --print but applies only to intermediary requests/responses.-q,--quiet: Do not print to stdout or stderr.Using quiet twice i.e. -qq will suppress warnings as well.
-S,--stream: Always stream the response body.-x,--compress: Content compressed (encoded) with Deflate algorithm.The Content-Encoding header is set to deflate.
Compression is skipped if it appears that compression ratio is negative. Compression can be forced by repeating this option.
Note: Compression cannot be used if the Content-Encoding request header is present.
-o,--output=FILE: Save output to FILE instead of stdout.-d,--download: Download the body to a file instead of printing it.The Accept-Encoding header is set to identity and any redirects will be followed.
-c,--continue: Resume an interrupted download. Requires --download and --output.--session=FILE: Create, or reuse and update a session.Within a session, custom headers, auth credentials, as well as any cookies sent by the server persist between requests.
--session-read-only=FILE: Create or read a session without updating it from the request/response exchange.-A,--auth-type=AUTH_TYPE: Specify the auth mechanism.[possible values:
basic,bearer,digest]-a,--auth=USER[:PASS] | TOKEN: Authenticate as USER with PASS (-A basic|digest) or with TOKEN (-A bearer).PASS will be prompted if missing. Use a trailing colon (i.e.
USER:) to authenticate with just a username.TOKEN is expected if --auth-type=bearer.
--ignore-netrc: Do not use credentials from .netrc.--offline: Construct HTTP requests without sending them anywhere.--check-status: (default) Exit with an error status code if the server replies with an error.The exit code will be 4 on 4xx (Client Error), 5 on 5xx (Server Error), or 3 on 3xx (Redirect) if --follow isn't set.
If stdout is redirected then a warning is written to stderr.
-F,--follow: Do follow redirects.--max-redirects=NUM: Number of redirects to follow. Only respected if --follow is used.--timeout=SEC: Connection timeout of the request.The default value is
0, i.e., there is no timeout limit.--proxy=PROTOCOL:URL: Use a proxy for a protocol. For example: --proxy https:http://proxy.host:8080.PROTOCOL can be
all,httporhttps.If your proxy requires credentials, put them in the URL, like so: --proxy http:socks5://user:[email protected]:8000.
You can specify proxies for multiple protocols by repeating this option.
The environment variables
ALL_PROXY,HTTP_PROXYandHTTPS_PROXYcan also be used, but are completely ignored if --proxy is passed.--verify=VERIFY: Ifno, skip SSL verification. If a file path, use it as a CA bundle.Specifying a CA bundle will disable the system's built-in root certificates.
falseinstead ofnoalso works. The default isyes(true).--cert=FILE: Use a client side certificate for SSL.--cert-key=FILE: A private key file to use with --cert.Only necessary if the private key is not contained in the cert file.
--ssl=VERSION: Force a particular TLS version.autogives the default behavior of negotiating a version with the server.[possible values:
auto,tls1,tls1.1,tls1.2,tls1.3]--native-tls: Use the system TLS library instead of rustls (if enabled at compile time).--https: Make HTTPS requests if not specified in the URL.--http-version=VERSION: HTTP version to use.[possible values:
1.0,1.1,2,2-prior-knowledge,3-prior-knowledge]--resolve=HOST:ADDRESS: Override DNS resolution for specific domain to a custom IP.You can override multiple domains by repeating this option.
Example: --resolve=example.com:127.0.0.1.
--interface=NAME: Bind to a network interface or local IP address.Example: --interface=eth0 --interface=192.168.0.2.
-4,--ipv4: Resolve hostname to ipv4 addresses only.-6,--ipv6: Resolve hostname to ipv6 addresses only.--unix-socket=FILE: Connect using a Unix domain socket.Example: xh :/index.html --unix-socket=/var/run/temp.sock.
-I,--ignore-stdin: Do not attempt to read stdin.This disables the default behaviour of reading the request body from stdin when a redirected input is detected.
It is recommended to pass this flag when using xh for scripting purposes. For more information, refer to https://httpie.io/docs/cli/best-practices.
--curl: Print a translation to a curl command.For translating the other way, try https://curl2httpie.online/.
--curl-long: Use the long versions of curl's flags.--generate=KIND: Generate shell completions or man pages. Possible values are:complete-bash: Generate completions for bashcomplete-elvish: Generate completions for elvishcomplete-fish: Generage completions for fishcomplete-nushell: Generate completions for nushellcomplete-powershell: Generate completions for powershellcomplete-zsh: Generate completions for zshman: Generate manual page in roff formatman-markdown: Generate manual page in markdown format
Example: xh --generate=complete-bash > xh.bash.
--help: Print help.-V,--version: Print version.
EXIT STATUS
0: Successful program execution.1: Usage, syntax or network error.2: Request timeout.3: Unexpected HTTP 3xx Redirection.4: HTTP 4xx Client Error.5: HTTP 5xx Server Error.6: Too many redirects.
ENVIRONMENT
XH_CONFIG_DIR:
Specifies where to look for config.json and named session data.
The default is~/.config/xhfor Linux/macOS and%APPDATA%\xhfor Windows.XH_HTTPIE_COMPAT_MODE:
Enables the HTTPie Compatibility Mode. The only current difference is that--check-statusis not enabled by default. An alternative to setting this
environment variable is to rename the binary to either http or https.REQUESTS_CA_BUNDLE,CURL_CA_BUNDLE:
Sets a custom CA bundle path.ALL_PROXY=[protocol://]<host>[:port]:
Sets the proxy server for all requests (unless overridden for a specific protocol).HTTP_PROXY=[protocol://]<host>[:port]:
Sets the proxy server to use for HTTP.HTTPS_PROXY=[protocol://]<host>[:port]:
Sets the proxy server to use for HTTPS.NO_PROXY:
List of comma-separated hosts for which to ignore the other proxy environment variables.*matches all host names.NETRC:
Location of the.netrcfile.NO_COLOR:
Disables output coloring. See https://no-color.orgRUST_LOG:
Configure low-level debug messages. See https://docs.rs/env_logger/0.11.3/env_logger/#enabling-logging
FILES
~/.config/xh/config.json:
xh configuration file. The only configurable option isdefault_options
which is a list of default shell arguments that gets passed toxh.
Example:json{ "default_options": ["--native-tls", "--style=solarized"] }~/.netrc,~/_netrc:
Auto-login information file.~/.config/xh/sessions:
Session data directory grouped by domain and port number.
EXAMPLES
Send a GET request:
xh httpbin.org/jsonSend a POST request with body {"name": "ahmed", "age": 24}:
xh httpbin.org/post name=ahmed age:=24Send a GET request to http://httpbin.org/json?id=5&sort=true:
xh get httpbin.org/json id==5 sort==trueSend a GET request and include a header named X-Api-Key with value 12345:
xh get Ihttpbin.org/json x-api-key:12345Send a POST request with body read from stdin:
echo "[1, 2, 3]" | xh post httpbin.org/postSend a PUT request and pipe the result to less:
xh put httpbin.org/put id:=49 age:=25 | lessDownload and save to res.json:
xh -d httpbin.org/json -o res.jsonMake a request with a custom user agent:
xh httpbin.org/get user-agent:foobarMake an HTTPS request to https://example.com:
xhs example.comREPORTING BUGS
xh's Github issues https://github.com/ducaale/xh/issues
SEE ALSO
curl(1), http(1)
HTTPie's online documentation https://httpie.io/docs/cli
--- METRICS ---
- Files Extracted: 4
- Estimated Token Budget: ~6498 tokens
- Canonical Reference: https://codewiki.google/github.com/ducaale/xh