zapreq 0.1.4

A fast, friendly HTTP client for the terminal
Documentation

zapreq

A fast, friendly HTTP client for the terminal — HTTPie reimagined in Rust.

Crates.io CI License Rust

zapreq installs an http binary. If you know HTTPie, you already know zapreq — same syntax, faster startup, lower memory, and a handful of features HTTPie never shipped.


Table of contents


Why zapreq

  • ~3 MB binary, ~5 ms startup. HTTPie ships ~15 MB and takes ~200 ms. ZapReq is compiled Rust — no interpreter, no import overhead.
  • HTTPie-compatible syntax. Every key=value, key:=value, key==value item works exactly as you expect.
  • Full auth coverage. Basic, Bearer, and Digest (RFC 7616, MD5 + SHA-256) with an automatic 401 retry cycle for Digest.
  • Session persistence. Cookies, headers, and auth are saved to ~/.config/zapreq/sessions/ and restored on the next request.
  • Environment profiles. Switch between dev, staging, and prod with one flag.
  • Request collections. Save a request by name, replay it later — Postman-style, entirely in the terminal.
  • AI assistant. Describe a request in plain English; zapreq generates and runs it.
  • Response diffing. Compare two endpoints side by side, key by key.
  • Zero Python dependency. One binary, no virtualenv, no pip.

Install

cargo install zapreq

Pre-built binaries for Linux, macOS (x86 + ARM), and Windows are attached to every GitHub release. Download and place the binary on your PATH if you do not have a Rust toolchain.

Package managers

# Arch Linux (AUR)
yay -S zapreq

# macOS / Linux (Homebrew tap)
brew tap MFAIZAN20/zapreq
brew install zapreq

Quick start

# GET request
http GET https://httpbin.org/get

# POST with JSON body (inferred from data items)
http POST https://httpbin.org/post name=faizan age:=22

# Form-encoded body
http --form POST https://httpbin.org/post field=value

# Custom headers
http GET https://httpbin.org/headers Accept:application/json X-Token:abc123

# Query parameters
http GET https://httpbin.org/get page==2 limit==10

# Basic auth
http --auth user:pass https://httpbin.org/basic-auth/user/pass

# Bearer token
http --auth-type bearer --auth "$TOKEN" https://api.example.com/me

# Named session (saves cookies + auth for next time)
http --session myapi POST https://api.example.com/login username=faizan password=secret
http --session myapi GET  https://api.example.com/me

# Download a file with a progress bar
http --download https://example.com/archive.zip

# Compare two API versions
http diff https://api.example.com/v1/user/1 https://api.example.com/v2/user/1

Request items

Items are positional arguments after the URL. The operator between key and value determines what the item does.

Operator Type Example
key:value Request header Accept:application/json
key=value String body field name=faizan
key:=value Raw JSON body field active:=true or count:=42
key==value Query string parameter page==2
key@/path File upload (multipart) avatar@/tmp/photo.png
key@/path;type=mime File upload with explicit MIME blob@/tmp/data.bin;type=application/octet-stream
key=@/path String field read from file payload=@/tmp/body.txt
key:=@/path JSON field read from file config:=@/tmp/opts.json

Operator precedence (strict, evaluated left to right): := and :=@==:= and =@@.

JSON body is the default when data items are present. Pass --form for application/x-www-form-urlencoded or --multipart for multipart/form-data.


Output control

# Print only response headers
http --print=h GET https://httpbin.org/get

# Print request + response headers (no body)
http --print=Hh GET https://httpbin.org/get

# Print everything
http --verbose GET https://httpbin.org/get

# Disable all formatting and colour (good for piping)
http --pretty=none GET https://httpbin.org/get | jq .

# Change syntax theme
http --style=dracula GET https://httpbin.org/json

--print flags — combine freely:

Flag Meaning
H Request headers
B Request body
h Response headers
b Response body

Default is hb (response headers + body). --verbose is shorthand for HBhb.

--pretty modes: all (default when TTY), colors, format, none.

--style themes: monokai (default), solarized, dracula, autumn.


Authentication

# HTTP Basic
http --auth user:pass https://api.example.com/resource

# Bearer token
http --auth-type bearer --auth "$TOKEN" https://api.example.com/resource

# HTTP Digest (RFC 7616 — MD5 and SHA-256 supported, automatic 401 retry)
http --auth-type digest --auth user:pass https://api.example.com/resource

The --auth-type flag defaults to basic. Credentials passed via --auth are masked (user:****) in --verbose output.


Sessions

Named sessions persist headers, cookies, and auth credentials between requests. Session files live in ~/.config/zapreq/sessions/{hostname}/{name}.json.

# Log in — session is created and cookies are saved
http --session prod POST https://api.example.com/login username=faizan password=secret

# Subsequent requests reuse the saved session
http --session prod GET https://api.example.com/me
http --session prod GET https://api.example.com/orders

# Load a session but do not update it after the response
http --session-read-only prod GET https://api.example.com/me

Session file format:

{
  "headers":  { "X-Client": "zapreq" },
  "auth":     { "type": "basic", "username": "faizan", "password": "secret" },
  "cookies":  [{ "name": "sid", "value": "abc", "domain": "api.example.com", "path": "/" }],
  "meta":     { "created": "2026-02-01T10:00:00Z", "last_used": "2026-05-01T14:22:00Z" }
}

Environment profiles

Profiles let you switch base URL, headers, and variable values with a single flag. Profile files live in ~/.config/zapreq/envs/{name}.json.

{
  "base_url":  "https://api.example.com",
  "headers":   { "X-API-Version": "2" },
  "variables": { "USER_ID": "42", "TOKEN": "prod-secret" }
}
# Use a named profile
http --env-profile prod GET /users/{USER_ID}

# Combine with a collection
http run get-user --env-profile staging

Variable tokens {KEY} are substituted in the URL and in all request item values before the request is built.


Request collections

Collections let you save a request by name and replay it later, optionally with a different environment profile.

# Save a request
http save login -- POST https://api.example.com/login username=faizan password={PASSWORD}

# List saved requests
http list

# Run a saved request
http run login

# Run with a profile (profile variables fill {PASSWORD})
http run login --env-profile prod

# Delete a saved request
http delete login

Collection files live in ~/.config/zapreq/collections/{alias}.json.


AI assistant

Set an OpenAI-compatible API key:

export ZAPREQ_AI_KEY=sk-...

Describe your request in plain English:

http ai "POST to https://api.example.com/users with name Faizan and role admin"

ZapReq prints the generated command before executing it so you can see exactly what it built. The assistant uses a structured JSON prompt — it never guesses; it constructs a concrete request from your description.


Response diffing

Compare two API endpoints key by key. ZapReq flattens both JSON responses into dot-notation paths and shows what changed.

http diff https://api.example.com/v1/user/42 https://api.example.com/v2/user/42

Output:

A: GET https://api.example.com/v1/user/42  →  200 OK
B: GET https://api.example.com/v2/user/42  →  200 OK

  user.id          42
  user.name        "faizan"
- user.role        "admin"          (only in A)
+ user.role        "viewer"         (only in B)
~ user.updated_at  "2025-01-01" → "2026-05-01"

Green lines are additions, red are removals, yellow are value changes.


Download mode

# Download to current directory (filename from Content-Disposition or URL)
http --download https://example.com/archive.zip

# Save to a specific path
http --download --output ~/Downloads/archive.zip https://example.com/archive.zip

# Resume a partial download
http --download --continue --output archive.zip https://example.com/archive.zip

A progress bar is shown during the download:

[████████████░░░░░░░░] 4.2 MB / 10.0 MB  ·  1.2 MB/s  ·  ETA 5s
✔ Downloaded: archive.zip  (10.0 MB in 8.3s  ·  avg 1.2 MB/s)

Configuration

Config file: ~/.config/zapreq/config.json

{
  "default_options": ["--style=monokai"],
  "default_scheme":  "https",
  "plugins_dir":     "~/.config/zapreq/plugins",
  "output_theme":    "monokai",
  "pretty":          "all",
  "verify":          true
}
Key Type Default Description
default_options string[] [] Flags prepended before every invocation
default_scheme string https Scheme used when URL has no scheme
plugins_dir string ~/.config/zapreq/plugins Directory scanned for plugin manifests
output_theme string monokai Default syntax theme
pretty string all Default pretty mode
verify bool true TLS certificate verification

Precedence order (highest to lowest):

Explicit CLI flags
  ↓
ZAPREQ_DEFAULT_OPTIONS environment variable
  ↓
config.json default_options
  ↓
Built-in defaults

Plugins

Built-in plugins (basic, bearer, digest) are always available. Third-party plugins are discovered from plugins_dir via .toml manifest files.

# List all registered plugins
http plugins list

# Install instructions for a community plugin
http plugins install zapreq-plugin-aws

Manifest format (~/.config/zapreq/plugins/my-plugin.toml):

[plugin]
name        = "my-auth"
version     = "1.0.0"
description = "Custom HMAC authentication"
auth_types  = ["hmac"]

See the plugin authoring guide for how to build and distribute a zapreq plugin.


Comparison with HTTPie

Feature HTTPie zapreq
JSON / form / multipart
Sessions
Basic + Bearer auth
Digest auth (RFC 7616)
Syntax-highlighted output
Environment profiles
Request collections
AI request assistant
Response diffing
Resume downloads
Native binary (no Python)
Binary size ~15 MB ~3 MB
Startup time ~200 ms ~5 ms

Contributing

# Clone
git clone https://github.com/MFAIZAN20/zapreq
cd zapreq

# Run tests
cargo test --all

# Lint
cargo clippy --all-targets --all-features -- -D warnings

# Format
cargo fmt --all

# Release build
cargo build --release

All pull requests must pass the CI matrix (Ubuntu, macOS, Windows × stable, beta) before merge. Please open an issue before starting work on a large feature.


License

Licensed under either of the following, at your option:

This is the standard dual license used across the Rust ecosystem (Rust itself, Cargo, tokio, serde, clap, reqwest). You may choose whichever license suits your project.

Copyright © 2026 Muhammad Faizan