HTTP request debugger for humans. "Why isn't my request working?" — this tool answers that, loud and specific, in under a second.
Free forever gift from vøiddo.
┌───────────────────────────────────────┐
│ httpwut https://api.example.com │
│ │
│ STATUS 401 Unauthorized ✗ │
│ bruh. unauthorized. missing or bad │
│ auth credentials. │
│ │
│ TIMING │
│ DNS ███░░░░░░░░░░░░░░░ 14ms │
│ TCP █░░░░░░░░░░░░░░░░░ 4ms │
│ TLS ████░░░░░░░░░░░░░░ 19ms │
│ TTFB ██████████████░░░░ 78ms │
│ Total 124ms │
└───────────────────────────────────────┘
You fire a request. Something's off. curl -v dumps a wall of text, Postman hides the timing, Insomnia needs a GUI. You just want to know what actually happened on the wire — DNS, TCP, TLS, TTFB, each phase measured, redirects walked, headers diffed, status explained in plain English (and, ok, a little "bruh").
httpwut is that. One binary. Zero config. Works in SSH sessions, CI logs, and Docker containers without pulling a thousand dependencies.
npm install -g @v0idd0/httpwutOr run it ad-hoc with npx:
npx -y @v0idd0/httpwut https://api.github.com/users/octocat# Simple GET with full debug info
httpwut https://api.github.com/users/octocat
# POST with JSON body
httpwut https://api.example.com/orders -X POST -d '{"sku":"abc","qty":1}'
# Bearer token + query params
httpwut https://api.example.com/users --bearer "$TOKEN" --query limit=10 --query page=2
# Basic auth
httpwut https://api.example.com -u admin:hunter2
# Body from file (or '-' for stdin)
httpwut https://api.example.com/ingest -X POST --data-file @./payload.json
cat payload.json | httpwut https://api.example.com/ingest -X POST --data-file -
# Follow redirects and print the chain
httpwut https://voiddo.com -L
# Full phase-timing breakdown
httpwut https://api.example.com --timing
# Retry on transient 5xx
httpwut https://api.example.com --retry 3 --retry-delay 500 --retry-on-status 502,503,504
# Compare two endpoints
httpwut https://api.example.com/v1/users --compare https://api.example.com/v2/users
# Status-only mode (exit code maps to 2xx / non-2xx, no output chrome)
httpwut https://api.example.com --status-only
# Machine-readable JSON envelope for scripts
httpwut https://api.example.com --json | jq .status
# Print the equivalent curl command (no request is made)
httpwut https://api.example.com --bearer "$TOKEN" --curl| Option | Description |
|---|---|
-X, --method <method> |
HTTP method (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS) |
-H, --header <header> |
Add header (can use multiple times) |
-d, --data <data> |
Request body (inline) |
--data-file <path> |
Read request body from file (use - for stdin) |
--query <k=v> |
Append a query param (can use multiple times) |
--bearer <token> |
Shortcut for Authorization: Bearer <token> |
-u, --user <user:pass> |
Basic auth shortcut |
| Option | Description |
|---|---|
-o, --output <file> |
Save response body to file |
--json |
Emit a single machine-readable JSON envelope |
--curl |
Print equivalent curl command (no request made) |
-v, --verbose |
Show everything (full headers, full body, timing) |
--headers-only |
Show only response headers |
--body-only |
Show only response body (raw, no chrome) |
--status-only |
Show only status code, exit 0 on 2xx / 1 otherwise |
--timing |
DNS / TCP / TLS / Wait / TTFB / Download breakdown |
| Option | Description |
|---|---|
-e, --expect <codes> |
Expected status codes, comma-separated |
-L, --follow |
Follow redirects (prints the chain) |
--compare <url> |
Diff headers / body / timing against another endpoint |
--insecure |
Skip SSL verification |
--timeout <ms> |
Request timeout (default 30000) |
--retry <n> |
Retry on network errors up to N times |
--retry-delay <ms> |
Base delay between retries, linear backoff |
--retry-on-status <codes> |
Also retry on these status codes (e.g. 502,503,504) |
httpwut measures each phase from the Node socket lifecycle — DNS lookup, TCP connect, TLS handshake, server wait, TTFB, and download — and prints them as stacked bars. No wrapping curl --trace-ascii, no guessing which phase is slow.
Every ECONNREFUSED, ENOTFOUND, EAI_AGAIN, CERT_HAS_EXPIRED, ERR_TLS_CERT_ALTNAME_INVALID, SELF_SIGNED_CERT_IN_CHAIN is translated. No more googling cryptic Node error codes.
Every 4xx and 5xx gets a one-liner in plain English. Includes modern codes most curl wrappers ignore: 418, 422, 425, 426, 429, 451, 511, 507, 508.
--compare <url> fires two requests, diffs status + every header + body + timing. Great for A/B testing load balancers, canary deploys, and "is this proxy actually transparent?"
--follow hops up to 10 redirects and prints every step with status, URL, and color coding.
--json emits a single JSON object with ok / url / status / headers / body / timing / redirectChain / statusHelp — drop it straight into jq, GitHub Actions matrices, or uptime scripts.
--curl prints the exact curl command that would produce the same request — method, headers, body, -k, all of it — without actually firing. Perfect for pasting into bug reports.
--retry 3 --retry-on-status 502,503,504 retries on network errors and configurable status codes with linear backoff. Reports (after N attempts) in the final status block so you know it wasn't a first-shot win.
| Code | Meaning |
|---|---|
0 |
Response status is 2xx |
1 |
Response status is non-2xx OR the request itself failed |
2 |
Invalid flags (e.g. both --data and --data-file) |
const { makeRequestWithRetries, getStatusHelp } = require('@v0idd0/httpwut/src/requester');
const res = await makeRequestWithRetries('https://api.example.com/ping', {
method: 'GET',
timeout: 5000,
retries: 2,
retryDelay: 300,
retryOnStatus: [502, 503, 504],
});
console.log(res.status, getStatusHelp(res.status), res.timing);Exports: makeRequest, makeRequestWithRetries, followRedirects, parseHeaders, getErrorHelp, getStatusHelp, isSuccess, formatJson, truncate, compareResponses, toCurl, buildUrl, ERROR_HELP, STATUS_HELP.
vøiddo builds sharp, free-forever CLIs for devs who are tired of paywalls:
@v0idd0/jsonyo— JSON that yells at you when it's broken@v0idd0/tokcount— token counter for 60+ LLMs (GPT-5.4, Claude Opus 4.7, Gemini 3.1, Llama 4, Grok 4.1)@v0idd0/ctxstuff— stuff a repo into an LLM context window without the OOM@v0idd0/promptdiff— diff two prompts, see token impact + word-frequency delta
Full catalog: voiddo.com/tools.
MIT © vøiddo — free forever, no asterisks.
- Docs: https://voiddo.com/tools/httpwut/
- Source: https://github.com/voidd0/httpwut
- npm: https://npmjs.com/package/@v0idd0/httpwut
- Studio: https://voiddo.com
- Issues: https://github.com/voidd0/httpwut/issues
- Support: support@voiddo.com