CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-hyperquest

Make streaming HTTP requests with no connection pooling or idle timeouts

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

index.mddocs/

Hyperquest

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.

Package Information

  • Package Name: hyperquest
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install hyperquest

Core Imports

const hyperquest = require('hyperquest');

ESM (with compatible bundler):

import hyperquest from 'hyperquest';

Basic Usage

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));

Architecture

Hyperquest is built around these key components:

  • Stream-First Design: All requests return Node.js streams (readable for GET/HEAD/DELETE, duplex for POST/PUT)
  • No Connection Pooling: Sets agent: false by default to avoid the 5-connection limit
  • No Idle Timeouts: Uses maximum timeout value to prevent 2-minute hangs
  • Browser Compatibility: Works with Browserify for client-side usage
  • Minimal Dependencies: Only requires buffer-from, duplexer2, and through2

Capabilities

HTTP Requests

Create 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);
});

Request Configuration

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'); 
});

Events

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);
});

Options Object

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
});

Stream Properties

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);

Error Handling

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);
});

docs

index.md

tile.json