@hapi/wreck

Promise-based HTTP client utilities for Node.js, built for and by the hapi ecosystem.

Library
npm
v18.1.2
377stars
BSD 3-Clause License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
49/100Fair
Development Activity32
Maintenance0
Community84
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
70/100Good
Architecture75
Code Quality85
Innovation65
Learning Curve55

Wreck is a lightweight HTTP client for Node.js maintained by the hapi.js team. It wraps Node’s core http/https modules in a promise-based API, adding automatic redirect handling, connection-agent pooling, gzip decompression, and safe JSON parsing on top of the raw request/response cycle.

Unlike heavier HTTP clients, Wreck stays close to Node’s native request/response objects rather than replacing them, exposing the underlying http.ClientRequest via promise.req while still giving callers a simple get/post/put/patch/delete shortcut API. It is a direct dependency of the hapi framework’s ecosystem but works standalone in any Node.js project that needs a dependable, well-tested HTTP client.

What You Get

  • A promise-based request()/read() API with the raw Node.js request object still attached via promise.req
  • Shortcut methods (get, post, put, patch, delete) that combine the request and payload read in one call
  • Automatic redirect following with configurable limits, per-redirect hooks, and cross-origin credential stripping
  • Connection-pooling agents for HTTP and HTTPS (including an unauthorized-TLS variant) managed internally
  • Built-in gzip response decompression and safe JSON payload parsing via @hapi/bourne
  • A Cache-Control header parser and a toReadableStream() helper for turning buffers/strings into streams

Common Use Cases

  • Calling third-party REST APIs from a Node.js backend without pulling in a heavier HTTP client library
  • Server-to-server requests inside a hapi application where consistent error handling (via @hapi/boom) is expected
  • Following redirects safely while stripping Authorization/Cookie headers on cross-origin hops
  • Streaming large request payloads (e.g. file uploads) without buffering them fully in memory first

Under The Hood

Architecture Wreck is built around a single internals.Client class in lib/index.js that composes three small helper modules: payload.js (a Readable stream wrapper for turning buffers/strings into streams), recorder.js (a Writable collector used to buffer response bodies with a maxBytes guard), and tap.js (used to shadow-copy streamed request payloads so they can be replayed across a redirect). request() returns a promise while delegating to _request(), which talks to Node’s http/https modules directly, tracks a _trace array of the method/URL for every hop, and recursively re-invokes itself to follow redirects — including cross-origin header stripping for sensitive credential headers. read()/_read() mirror this pattern for consuming a response body through the Recorder stream with optional gunzip and JSON parsing. Shortcut methods (get/post/etc.) are thin wrappers that call request() then read() and normalize non-2xx responses into a thrown Boom error carrying the response and payload.

Tech Stack The library is plain JavaScript with hand-maintained TypeScript declarations (lib/index.d.ts) rather than a TypeScript build step. It depends only on other hapi-ecosystem packages — @hapi/boom for typed HTTP errors, @hapi/bourne for prototype-pollution-safe JSON parsing, and @hapi/hoek for object cloning/defaults/assertion helpers — layered directly on Node’s built-in http, https, zlib, stream, events, and url modules with no external HTTP dependency at all. Tests run via @hapi/lab with @hapi/code assertions, and CI is a reusable GitHub Actions workflow shared across the hapi.js org (hapijs/.github).

Code Quality The test suite is extensive (thousands of lines in test/index.js) and the test script enforces full statement coverage (lab -t 100), so no code path ships untested. Errors are explicit and typed via Boom rather than swallowed, internal state uses a consistent internals namespacing convention typical of hapi.js projects, and public types are hand-authored and kept in sync with the implementation. Native assert-style guards (via Hoek.assert) validate option combinations early and reject invalid input with clear messages.

API Design The public surface is deliberately small: a default client instance is exported directly, defaults() produces scoped clients with merged option overrides, and the shortcut methods cover the common HTTP verbs in one call each. Thoughtful defaults stand out — cross-origin redirects strip Authorization/Cookie/Proxy-Authorization headers automatically, JSON parsing uses a safe parser that blocks prototype-pollution payloads, and the returned promise still exposes the underlying http.ClientRequest for callers who need lower-level access (e.g. to abort() a request). Getting started requires no configuration at all — Wreck.get(url) is enough for the common case.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search