xh
Friendly and fast HTTP client (HTTPie-compatible).
Official WebsiteFeatures
HTTPie CompatibleFastColor OutputJSON Support
Replaces
curlInstallation
Homebrew
brew install xhPacman (Arch)
pacman -S xhCargo (Rust)
cargo install xhWhy 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 xhLinux
Linux Installation
# Using Cargo
cargo install xh
# On Arch Linux
pacman -S xhWindows
Windows Installation
# Using Cargo
cargo install xhSetup 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 permanentVerify Installation
Verification
# Check version
xh --version
# Get help
xh --help
# Quick test
xh https://httpbin.org/getBasic 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/1Adding 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.comOutput 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
| Syntax | Type | Example |
|---|---|---|
key=value | String field | name=John |
key:=value | JSON value | age:=30 |
key@file | From file content | data@request.json |
Header:value | Request header | Authorization:Bearer token |
Header; | Empty header | X-Custom-Header; |
key==value | Query string | filter==active |
Common Options
| Option | Description | Example |
|---|---|---|
-j, --json | Send JSON (default for POST) | xh -j POST api.example.com |
-f, --form | Send form data | xh -f POST api.example.com |
-b, --body | Print response body only | xh -b GET api.example.com |
-h, --headers | Print headers only | xh -h GET api.example.com |
-v, --verbose | Show request and response | xh -v POST api.example.com |
-p | Pretty print (default) | xh -p GET api.example.com |
--follow | Follow redirects | xh --follow GET example.com |
-a, --auth | Basic authentication | xh -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/123Authentication
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.comForm 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.pdfQuery 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.txtConfiguration 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.zipxh vs curl vs HTTPie
| Feature | curl | HTTPie | xh |
|---|---|---|---|
| Syntax | Complex | Intuitive | Intuitive |
| Speed | Fast | Slower | Very Fast |
| Output | Raw | Colorful | Colorful |
| Learning Curve | Steep | Easy | Easy |
| JSON Support | Manual | Native | Native |
| HTTPie Compatible | - | Official | Drop-in |
Tips and Best Practices
- •xh is a drop-in replacement for HTTPie - use
alias http=xhfor seamless migration - •Use
-vflag during debugging to see both request and response - •JSON is the default for POST requests - use
--formfor form data - •Pipe response to
jqfor powerful JSON filtering and transformation - •Use
@file.jsonsyntax to send request bodies from files - •Save sessions for APIs you frequently interact with using
--session