Terminal GuideTerminal Guide

xh

Modern CLI
macOSLinuxWindows
Rust

Friendly and fast HTTP client (HTTPie-compatible).

Official Website

Features

HTTPie CompatibleFastColor OutputJSON Support
Replaces
curl

Installation

Homebrew
brew install xh
Pacman (Arch)
pacman -S xh
Cargo (Rust)
cargo install xh

Why Use xh?

xh is a faster, modern HTTP client that maintains HTTPie compatibility while offering superior performance. It makes making HTTP requests from the command line intuitive and enjoyable with beautiful, colorized output.

Lightning Fast

Written in Rust for exceptional performance compared to Python-based HTTPie.

Beautiful Output

Colorized requests and responses with intelligent formatting for JSON.

HTTPie Compatible

Drop-in replacement for HTTPie - use the same syntax and options you know.

Smart Data Handling

Automatic JSON/form encoding and request body formatting based on content type.

Installation

macOS

macOS Installation
# Using Homebrew
brew install xh

Linux

Linux Installation
# Using Cargo
cargo install xh

# On Arch Linux
pacman -S xh

Windows

Windows Installation
# Using Cargo
cargo install xh

Setup HTTPie Alias

Optional Alias Setup
# Optionally alias http to xh
alias http='xh'
alias https='xh --secure'

# Add to ~/.bashrc or ~/.zshrc to make it permanent

Verify Installation

Verification
# Check version
xh --version

# Get help
xh --help

# Quick test
xh https://httpbin.org/get

Basic Usage

Simple HTTP Requests

Basic Requests
# GET request (default)
xh https://httpbin.org/get

# GET request to a host
xh GET https://api.github.com/repos/httpwg/http-core

# POST request with JSON data
xh POST https://httpbin.org/post name=John age:=30

# HEAD request
xh HEAD https://example.com

# DELETE request
xh DELETE https://api.example.com/resource/1

Adding Headers and Data

Headers and Data
# Add custom headers
xh GET https://api.example.com Authorization:"Bearer token123"

# Add headers with multiple values
xh POST https://httpbin.org/post   name=Alice   email=alice@example.com   age:=25

# Form data instead of JSON
xh --form POST https://httpbin.org/post   username=john   password=secret

# JSON data (default)
xh POST https://httpbin.org/post   name=Bob   email=bob@example.com

Output Example

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 417
{
"args": ,
"headers": {...
"origin": "192.168.1.1",
"url": "https://httpbin.org/get"
}

Syntax-highlighted JSON response with colored headers.

Request Syntax

SyntaxTypeExample
key=valueString fieldname=John
key:=valueJSON valueage:=30
key@fileFrom file contentdata@request.json
Header:valueRequest headerAuthorization:Bearer token
Header;Empty headerX-Custom-Header;
key==valueQuery stringfilter==active

Common Options

OptionDescriptionExample
-j, --jsonSend JSON (default for POST)xh -j POST api.example.com
-f, --formSend form dataxh -f POST api.example.com
-b, --bodyPrint response body onlyxh -b GET api.example.com
-h, --headersPrint headers onlyxh -h GET api.example.com
-v, --verboseShow request and responsexh -v POST api.example.com
-pPretty print (default)xh -p GET api.example.com
--followFollow redirectsxh --follow GET example.com
-a, --authBasic authenticationxh -a user:pass GET api.example.com

Practical Examples

API Testing

REST API Operations
# Get user list
xh GET https://api.example.com/users

# Create new user
xh POST https://api.example.com/users   name=Alice   email=alice@example.com   role=admin

# Update user
xh PATCH https://api.example.com/users/123   status=active

# Delete user
xh DELETE https://api.example.com/users/123

Authentication

Authentication Methods
# Basic auth
xh -a username:password GET https://api.example.com/data

# Bearer token
xh GET https://api.example.com/data   Authorization:"Bearer eyJhbGciOiJIUzI1NiIs..."

# API key header
xh GET https://api.example.com/data   X-API-Key:sk_live_abcd1234

# Multiple headers
xh GET https://api.example.com/data   Authorization:"Bearer token"   X-Request-ID:"req-123"

Working with JSON

JSON Operations
# POST JSON data
xh POST https://api.example.com/items   name="New Item"   price:=99.99   inStock:=true

# Send from file
xh POST https://api.example.com/items @data.json

# Pretty print JSON response
xh -p GET https://api.example.com/data

# Output raw response
xh -b GET https://api.example.com/data | jq '.items[]'

Debugging and Inspection

Debugging
# Show full request and response
xh -v POST https://api.example.com/data name=test

# Show headers only
xh -h GET https://api.example.com/data

# Show body only
xh -b GET https://api.example.com/data

# Follow redirects
xh --follow GET https://example.com

# Check response headers
xh -h HEAD https://api.example.com

Form Submissions

Form Handling
# Submit form data
xh --form POST https://example.com/login   username=john   password=secret   remember=on

# File upload
xh --form POST https://example.com/upload   file@./photo.jpg

# Multi-part form
xh --form POST https://api.example.com/submit   name=Alice   description="My project"   document@report.pdf

Query Parameters

Query Parameters
# Query parameters
xh GET https://api.example.com/search   q==python   page==1   limit==10

# Mixed path and query
xh GET https://api.example.com/users/123   include==profile   fields==name,email

# URL with query string
xh GET 'https://api.example.com/search?q=python&limit=10'

Advanced Usage

Shell Aliases

Useful Aliases
# ~/.bashrc or ~/.zshrc

# Alias http to xh
alias http='xh'
alias https='xh'

# Common API endpoints
alias myapi='xh https://api.myproject.com'

# With auth token
alias authapi='xh https://api.example.com Authorization:"Bearer $API_TOKEN"'

# Pretty print by default
alias xhp='xh -p'

Scripting and Automation

Scripting
# Save response to file
xh GET https://api.example.com/data > response.json

# Pipe to jq for processing
xh -b GET https://api.example.com/users | jq '.[] | .name'

# Loop through endpoints
for id in {1..10}; do
  xh GET https://api.example.com/items/$id
done

# Store results
xh -b POST https://api.example.com/login   email=user@example.com   password=secret | jq -r '.token' > token.txt

Configuration Files

Session Management
# Save request as session
xh https://api.example.com/users --session=myapi   Authorization:"Bearer token123"

# Reuse session
xh https://api.example.com/posts --session=myapi

# Session with timeout
xh https://api.example.com/data --session=temp --session-read-only

# Sessions directory
ls ~/.config/xh/sessions/

Advanced Options

Advanced Options
# Ignore SSL verification (for development)
xh --verify=no GET https://self-signed.example.com

# Custom timeout
xh --timeout=30 GET https://slow-api.example.com

# Custom proxy
xh --proxy=http://proxy.example.com:8080 GET https://api.example.com

# Download file
xh --download GET https://example.com/file.zip

# Continue interrupted download
xh --download --continue GET https://example.com/large-file.zip

xh vs curl vs HTTPie

FeaturecurlHTTPiexh
SyntaxComplexIntuitiveIntuitive
SpeedFastSlowerVery Fast
OutputRawColorfulColorful
Learning CurveSteepEasyEasy
JSON SupportManualNativeNative
HTTPie Compatible-OfficialDrop-in

Tips and Best Practices

  • xh is a drop-in replacement for HTTPie - use alias http=xh for seamless migration
  • Use -v flag during debugging to see both request and response
  • JSON is the default for POST requests - use --form for form data
  • Pipe response to jq for powerful JSON filtering and transformation
  • Use @file.json syntax to send request bodies from files
  • Save sessions for APIs you frequently interact with using --session
Written by Dai AokiPublished: 2026-01-20

Related Articles

Explore More