CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-undici

An HTTP/1.1 client, written from scratch for Node.js

Pending
Overview
Eval results
Files

core-http.mddocs/

Core HTTP APIs

High-performance HTTP request methods optimized for different use cases, from simple requests to complex streaming scenarios.

Capabilities

request

Promise-based HTTP requests with the highest performance. Ideal for most HTTP client needs.

/**
 * Performs an HTTP request with high performance
 * @param url - The URL to request
 * @param options - Request configuration options
 * @returns Promise resolving to response data
 */
function request(url: string | URL, options?: RequestOptions): Promise<ResponseData>;

interface RequestOptions {
  method?: string;
  headers?: IncomingHttpHeaders;
  body?: BodyInit;
  query?: Record<string, any>;
  idempotent?: boolean;
  blocking?: boolean;
  upgrade?: boolean;
  headersTimeout?: number;
  bodyTimeout?: number;
  reset?: boolean;
  throwOnError?: boolean;
  expectContinue?: boolean;
  signal?: AbortSignal;
  opaque?: unknown;
}

interface ResponseData {
  statusCode: number;
  headers: IncomingHttpHeaders;
  body: BodyReadable;
  trailers: Record<string, string>;
  opaque: unknown;
  context: {
    history: readonly URL[];
  };
}

Usage Examples:

import { request } from 'undici';

// Simple GET request
const { statusCode, headers, body } = await request('https://api.example.com/users');
const users = await body.json();

// POST request with JSON body
const response = await request('https://api.example.com/users', {
  method: 'POST',
  headers: {
    'content-type': 'application/json'
  },
  body: JSON.stringify({ name: 'Alice', email: 'alice@example.com' })
});

// Request with timeout and error handling
try {
  const { body } = await request('https://slow-api.example.com/data', {
    headersTimeout: 5000,
    bodyTimeout: 10000,
    throwOnError: true
  });
  const data = await body.json();
} catch (error) {
  console.error('Request failed:', error.message);
}

stream

Streaming HTTP requests for handling large payloads efficiently with backpressure support.

/**
 * Performs a streaming HTTP request
 * @param url - The URL to request
 * @param options - Request configuration options
 * @param factory - Factory function to create the stream handler
 * @returns Promise resolving to stream data
 */
function stream(
  url: string | URL, 
  options: RequestOptions, 
  factory: StreamFactory
): Promise<StreamData>;

type StreamFactory = (data: StreamFactoryData) => Writable;

interface StreamFactoryData {
  statusCode: number;
  headers: IncomingHttpHeaders;
  opaque: unknown;
}

interface StreamData {
  opaque: unknown;
  trailers: Record<string, string>;
}

Usage Examples:

import { stream } from 'undici';
import { createWriteStream } from 'fs';

// Download large file
await stream('https://example.com/large-file.zip', {}, ({ statusCode, headers }) => {
  if (statusCode === 200) {
    return createWriteStream('./large-file.zip');
  }
  throw new Error(`Request failed with status ${statusCode}`);
});

// Stream processing with custom writable
await stream('https://api.example.com/stream-data', {
  method: 'GET',
  headers: { 'accept': 'application/json' }
}, ({ statusCode }) => {
  return new Writable({
    write(chunk, encoding, callback) {
      // Process each chunk of data
      const data = JSON.parse(chunk.toString());
      console.log('Received:', data);
      callback();
    }
  });
});

pipeline

Pipeline HTTP requests with Node.js streams for maximum control over data flow.

/**
 * Creates a pipeline for streaming HTTP requests
 * @param url - The URL to request
 * @param options - Request configuration options
 * @param handler - Pipeline handler for processing the stream
 * @returns Duplex stream for the pipeline
 */
function pipeline(
  url: string | URL, 
  options: PipelineOptions, 
  handler: PipelineHandler
): Duplex;

interface PipelineOptions extends RequestOptions {
  objectMode?: boolean;
}

type PipelineHandler = (data: PipelineHandlerData) => Readable | Transform;

interface PipelineHandlerData {
  statusCode: number;
  headers: IncomingHttpHeaders;
  opaque: unknown;
  body: BodyReadable;
}

Usage Examples:

import { pipeline } from 'undici';
import { Transform } from 'stream';
import { createReadStream, createWriteStream } from 'fs';

// Upload file with transformation
const uploadStream = pipeline('https://api.example.com/upload', {
  method: 'POST',
  headers: { 'content-type': 'application/octet-stream' }
}, ({ statusCode }) => {
  if (statusCode !== 200) {
    throw new Error(`Upload failed: ${statusCode}`);
  }
  return new Transform({
    transform(chunk, encoding, callback) {
      // Process upload response
      callback(null, chunk);
    }
  });
});

// Pipe file through upload
createReadStream('./file.txt').pipe(uploadStream).pipe(process.stdout);

connect

HTTP CONNECT method for establishing tunnels, typically used for proxying.

/**
 * Establishes an HTTP CONNECT tunnel
 * @param url - The URL to connect to
 * @param options - Connection options
 * @returns Promise resolving to connection data
 */
function connect(url: string | URL, options?: ConnectOptions): Promise<ConnectData>;

interface ConnectOptions {
  headers?: IncomingHttpHeaders;
  signal?: AbortSignal;
  opaque?: unknown;
}

interface ConnectData {
  statusCode: number;
  headers: IncomingHttpHeaders;
  socket: Duplex;
  opaque: unknown;
}

Usage Examples:

import { connect } from 'undici';

// Establish CONNECT tunnel through proxy
const { socket, statusCode } = await connect('https://proxy.example.com:8080', {
  headers: {
    'proxy-authorization': 'Basic ' + Buffer.from('user:pass').toString('base64')
  }
});

if (statusCode === 200) {
  // Use socket for tunneled communication
  socket.write('GET /api/data HTTP/1.1\r\nHost: api.example.com\r\n\r\n');
  socket.on('data', (chunk) => {
    console.log(chunk.toString());
  });
}

upgrade

HTTP protocol upgrade requests for switching protocols (e.g., WebSocket handshake).

/**
 * Performs an HTTP protocol upgrade
 * @param url - The URL to upgrade
 * @param options - Upgrade options
 * @returns Promise resolving to upgrade data
 */
function upgrade(url: string | URL, options?: UpgradeOptions): Promise<UpgradeData>;

interface UpgradeOptions {
  headers?: IncomingHttpHeaders;
  protocol?: string;
  signal?: AbortSignal;
  opaque?: unknown;
}

interface UpgradeData {
  headers: IncomingHttpHeaders;
  socket: Duplex;
  opaque: unknown;
}

Usage Examples:

import { upgrade } from 'undici';

// WebSocket handshake
const { socket, headers } = await upgrade('ws://localhost:3000/socket', {
  headers: {
    'upgrade': 'websocket',
    'connection': 'upgrade',
    'sec-websocket-key': 'dGhlIHNhbXBsZSBub25jZQ==',
    'sec-websocket-version': '13'
  }
});

// Handle WebSocket communication
socket.on('data', (data) => {
  console.log('WebSocket data:', data);
});

Types

Body Types

type BodyInit = 
  | ArrayBuffer 
  | AsyncIterable<Uint8Array> 
  | Blob 
  | FormData 
  | Iterable<Uint8Array> 
  | NodeJS.ArrayBufferView 
  | URLSearchParams 
  | null 
  | string;

interface BodyReadable extends Readable {
  arrayBuffer(): Promise<ArrayBuffer>;
  blob(): Promise<Blob>;
  bytes(): Promise<Uint8Array>;
  json(): Promise<any>;
  text(): Promise<string>;
}

Header Types

type IncomingHttpHeaders = Record<string, string | string[]>;
type OutgoingHttpHeaders = Record<string, string | string[] | number>;

Install with Tessl CLI

npx tessl i tessl/npm-undici

docs

caching.md

connection-management.md

cookies.md

core-http.md

errors.md

global-config.md

headers-body.md

index.md

interceptors.md

mock-testing.md

web-standards.md

tile.json