Hyperquest is a Node.js HTTP client library that treats HTTP requests as streaming transport. It solves critical problems with Node.js core HTTP functionality by eliminating connection pooling (default limit of 5 concurrent connections) and idle timeouts (2 minutes default) that cause applications to hang unexpectedly in production. Hyperquest provides a streaming API similar to the popular 'request' module but with better performance characteristics.
npm install hyperquestconst hyperquest = require('hyperquest');ESM (with compatible bundler):
import hyperquest from 'hyperquest';const hyperquest = require('hyperquest');
// Simple GET request - returns readable stream
const req = hyperquest('http://api.example.com/data');
req.pipe(process.stdout);
// POST request with data - returns duplex stream
const postReq = hyperquest.post('http://api.example.com/submit');
postReq.write('{"message": "hello"}');
postReq.end();
// Handle response
postReq.on('response', (res) => {
console.log('Status:', res.statusCode);
console.log('Headers:', res.headers);
});
// Collect response data
let data = '';
postReq.on('data', (chunk) => data += chunk);
postReq.on('end', () => console.log('Response:', data));Hyperquest is built around these key components:
agent: falseCreate streaming HTTP requests with various methods and options.
/**
* Create an outgoing HTTP request
* @param {string|object} uri - Request URI or options object
* @param {object} [opts={}] - Request options
* @param {function} [cb] - Optional callback for error/response events
* @returns {Stream} Readable stream (GET/HEAD/DELETE) or duplex stream (POST/PUT)
*/
function hyperquest(uri, opts, cb);
/**
* Create a GET request (alias for hyperquest)
* @param {string|object} uri - Request URI or options object
* @param {object} [opts={}] - Request options
* @param {function} [cb] - Optional callback for error/response events
* @returns {Stream} Readable stream
*/
hyperquest.get(uri, opts, cb);
/**
* Create a POST request
* @param {string|object} uri - Request URI or options object
* @param {object} [opts={}] - Request options
* @param {function} [cb] - Optional callback for error/response events
* @returns {Stream} Duplex stream (readable and writable)
*/
hyperquest.post(uri, opts, cb);
/**
* Create a PUT request
* @param {string|object} uri - Request URI or options object
* @param {object} [opts={}] - Request options
* @param {function} [cb] - Optional callback for error/response events
* @returns {Stream} Duplex stream (readable and writable)
*/
hyperquest.put(uri, opts, cb);
/**
* Create a DELETE request
* @param {string|object} uri - Request URI or options object
* @param {object} [opts={}] - Request options
* @param {function} [cb] - Optional callback for error/response events
* @returns {Stream} Readable stream
*/
hyperquest.delete(uri, opts, cb);Usage Examples:
const hyperquest = require('hyperquest');
// GET request
const getReq = hyperquest('http://api.example.com/users');
getReq.pipe(process.stdout);
// POST request with JSON data
const postReq = hyperquest.post('http://api.example.com/users');
postReq.setHeader('content-type', 'application/json');
postReq.write(JSON.stringify({ name: 'Alice', age: 25 }));
postReq.end();
// PUT request with authentication
const putReq = hyperquest.put('http://user:pass@api.example.com/users/123');
putReq.write('{"name": "Alice Updated"}');
putReq.end();
// DELETE request
const deleteReq = hyperquest.delete('http://api.example.com/users/123');
deleteReq.on('response', (res) => {
console.log('Deleted:', res.statusCode === 204);
});Configure requests with headers, authentication, and other options.
/**
* Set an outgoing HTTP header
* @param {string} key - Header name
* @param {string} value - Header value
* @returns {Stream} The request stream for chaining
* @throws {Error} Throws "request already sent" if called after request has been sent
*/
setHeader(key, value);
/**
* Set the request URI after creation
* @param {string} uri - Request URI
* @returns {Stream} The request stream for chaining
*/
setLocation(uri);Usage Examples:
const req = hyperquest.post('http://api.example.com/data');
req.setHeader('content-type', 'application/json');
req.setHeader('authorization', 'Bearer token123');
req.setLocation('http://api.example.com/updated-endpoint');
// Note: setHeader must be called before request is sent
req.on('request', () => {
// This would throw "request already sent" error:
// req.setHeader('late-header', 'value');
});Handle request lifecycle events.
/**
* Event fired with the underlying ClientRequest object
* @event request
* @param {http.ClientRequest} req - The underlying HTTP request object
*/
/**
* Event fired with the HTTP response object
* @event response
* @param {http.IncomingMessage} res - The HTTP response object
*/
/**
* Event fired when an error occurs
* @event error
* @param {Error} err - The error object
*/Usage Examples:
const req = hyperquest('http://api.example.com/data');
req.on('request', (clientReq) => {
console.log('Request started:', clientReq.method, clientReq.path);
});
req.on('response', (res) => {
console.log('Response received:', res.statusCode);
console.log('Content-Type:', res.headers['content-type']);
});
req.on('error', (err) => {
console.error('Request failed:', err.message);
});Configuration options for HTTP requests.
/**
* Request options object
* @typedef {Object} RequestOptions
* @property {string} [method='GET'] - HTTP method
* @property {Object} [headers={}] - HTTP headers object
* @property {string} [auth] - Basic auth in "user:pass" format
* @property {boolean|http.Agent} [agent=false] - HTTP agent (false disables pooling)
* @property {number} [timeout=2147483647] - Request timeout in milliseconds
* @property {string} [localAddress] - Local interface to bind for connections
* @property {string} [uri] - Request URI
* @property {boolean} [withCredentials] - Browser credentials option
* @property {string|Buffer} [pfx] - PFX certificate for HTTPS
* @property {string|Buffer} [key] - Private key for HTTPS
* @property {string|Buffer} [cert] - Certificate for HTTPS
* @property {string|Buffer|Array} [ca] - Certificate authorities for HTTPS
* @property {string} [ciphers] - Cipher suites for HTTPS
* @property {boolean} [rejectUnauthorized] - Verify server certificates for HTTPS
* @property {string} [secureProtocol] - SSL/TLS protocol version for HTTPS
*/Usage Examples:
// Basic options
const req = hyperquest('http://api.example.com/data', {
method: 'POST',
headers: { 'content-type': 'application/json' },
timeout: 5000
});
// Authentication via URL
const authReq = hyperquest('http://user:pass@api.example.com/private');
// Authentication via options
const authReq2 = hyperquest('http://api.example.com/private', {
auth: 'user:pass'
});
// HTTPS with custom certificates
const httpsReq = hyperquest('https://secure-api.example.com/data', {
ca: fs.readFileSync('ca-cert.pem'),
cert: fs.readFileSync('client-cert.pem'),
key: fs.readFileSync('client-key.pem'),
rejectUnauthorized: true
});Properties available on returned request streams.
/**
* Reference to hyperquest's internal request object containing metadata
* @property {Object} request - Object with method, headers, auth, options properties
*/
/**
* Reference to the HTTP response object (available after 'response' event)
* @property {http.IncomingMessage} response
*/Usage Examples:
const req = hyperquest('http://api.example.com/data');
req.on('response', (res) => {
// Access response via event parameter
console.log('Event response:', res.statusCode);
// Or via stream property (same object)
console.log('Stream response:', req.response.statusCode);
});
// Access underlying request object
console.log('Request method:', req.request.method);Handle various error conditions that may occur during HTTP requests.
Usage Examples:
const req = hyperquest('http://api.example.com/data');
req.on('error', (err) => {
if (err.code === 'ECONNREFUSED') {
console.error('Connection refused - server may be down');
} else if (err.code === 'ENOTFOUND') {
console.error('Host not found - check the URL');
} else if (err.code === 'ETIMEDOUT') {
console.error('Request timed out');
} else {
console.error('Request error:', err.message);
}
});
// Using callback for error handling
const req2 = hyperquest('http://api.example.com/data', (err, res) => {
if (err) {
console.error('Request failed:', err.message);
return;
}
console.log('Request succeeded:', res.statusCode);
});