Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/nodejs/undici/llms.txt

Use this file to discover all available pages before exploring further.

Client maps each instance to a single TCP or TLS connection to a given origin. Pipelining is disabled by default (pipelining: 1), meaning each connection handles one request at a time. You can raise pipelining to send multiple requests over the same connection concurrently, or use Pool when you need multiple connections to the same origin.
Client is a concrete implementation of Dispatcher. All methods (request, stream, pipeline, dispatch, connect, upgrade, close, destroy) are inherited from Dispatcher — see the Dispatcher reference for full method signatures.

Constructor

new Client(url, options?)

body.url
URL | string
required
The origin URL. Should include only the protocol, hostname, and port — no path, query string, or fragment.
body.options
ClientOptions
Configuration object. All fields are optional.
Basic instantiation
import { Client } from 'undici'

const client = new Client('https://api.example.com')
The client does not connect until the first request is dispatched.

Constructor options

Timeout options

body.headersTimeout
number | null
default:"300000"
Milliseconds to wait for the complete HTTP headers while not sending. Set to 0 to disable.
body.bodyTimeout
number | null
default:"300000"
Milliseconds of inactivity between body data chunks. Resets each time data is received. Set to 0 to disable.

Keep-alive options

body.keepAliveTimeout
number | null
default:"4000"
Milliseconds before an idle socket is closed. May be overridden by server keep-alive hints.
body.keepAliveMaxTimeout
number | null
default:"600000"
Maximum milliseconds for keep-alive, even if the server hints a higher value.
body.keepAliveTimeoutThreshold
number | null
default:"2000"
Milliseconds subtracted from server keep-alive hints to account for transport latency.

Pipelining and concurrency

body.pipelining
number | null
default:"1"
Number of concurrent requests to send over the single connection per RFC 7230. Set to 0 to disable keep-alive connections entirely.
Pipelining can reduce performance if used incorrectly. Consider your workload and any head-of-line blocking caused by long-running requests before raising this value.

Size limits

body.maxHeaderSize
number | null
default:"Node.js --max-http-header-size (16384)"
Maximum request header size in bytes.
body.maxResponseSize
number | null
default:"-1"
Maximum response body size in bytes. Set to -1 to disable.

Connection options

body.connect
ConnectOptions | Function | null
default:"null"
TLS/socket configuration. Pass an options object to configure TLS, or a custom connector function for full control over the socket.All Node.js TLS options are also accepted.
body.strictContentLength
boolean
default:"true"
Throw an error when the content-length header does not match the actual body length.
Disabling strictContentLength exposes your application to HTTP Request Smuggling attacks. Only disable this in fully trusted, controlled environments.

Address selection

body.autoSelectFamily
boolean
default:"false (Node ≥ 18.13)"
Enable Happy Eyeballs (RFC 8305 §5) to auto-select between IPv4 and IPv6.
body.autoSelectFamilyAttemptTimeout
number
default:"250 (Node ≥ 18.13)"
Milliseconds to wait for each address family attempt when autoSelectFamily is enabled.

HTTP/2 options

body.allowH2
boolean
default:"true"
Enable HTTP/2 via ALPN negotiation over TLS. The server must prefer HTTP/2 over HTTP/1.1.
body.maxConcurrentStreams
number
default:"100"
Maximum concurrent streams per HTTP/2 session. Can be overridden by the server’s SETTINGS frame.
body.initialWindowSize
number
default:"262144"
HTTP/2 stream-level flow-control window size in bytes (SETTINGS_INITIAL_WINDOW_SIZE). Higher than Node.js defaults for better throughput on high-bandwidth networks.
body.connectionWindowSize
number
default:"524288"
HTTP/2 connection-level flow-control window size in bytes.
body.pingInterval
number
default:"60000"
Milliseconds between HTTP/2 PING frames. Set to 0 to disable. Emits a ping event on the client with the round-trip duration.
HTTP/2 (allowH2) requires a TLS connection. The server must negotiate HTTP/2 via ALPN. Pseudo-headers (:path, :method, :scheme, :authority) are set automatically and cannot be overridden.

WebSocket options

body.webSocket
WebSocketOptions

Properties

client.closed
boolean
true after client.close() has been called.
client.destroyed
boolean
true after client.destroy() has been called or client.close() has fully completed.
client.pipelining
number
Read/write. The current pipelining factor. Changing this takes effect for future requests.
client.stats
ClientStats
Live statistics for this client.

Events

connect
event
Emitted when a socket connects. Parameters: origin: URL, targets: Dispatcher[].
disconnect
event
Emitted when the socket disconnects. The client reconnects automatically when client.size > 0. Parameters: origin: URL, targets: Dispatcher[], error: Error.
drain
event
Emitted when the request pipeline is no longer busy. Parameters: origin: URL.
error
event
Emitted for user-level errors such as exceptions thrown in onResponseError.

Code examples

Basic request
import { Client } from 'undici'

const client = new Client('https://api.example.com')

const { statusCode, headers, body } = await client.request({
  path: '/users/1',
  method: 'GET',
})

console.log(statusCode) // 200
const user = await body.json()

await client.close()
Pipelining — multiple concurrent requests on one connection
import { Client } from 'undici'

const client = new Client('https://api.example.com', { pipelining: 4 })

const results = await Promise.all([
  client.request({ path: '/a', method: 'GET' }),
  client.request({ path: '/b', method: 'GET' }),
  client.request({ path: '/c', method: 'GET' }),
  client.request({ path: '/d', method: 'GET' }),
])

console.log(results.map(r => r.statusCode))
await client.close()
Custom TLS connector
import { Client, buildConnector } from 'undici'

const connector = buildConnector({ rejectUnauthorized: false })

const client = new Client('https://localhost:3000', {
  connect(opts, cb) {
    connector(opts, (err, socket) => {
      if (err) return cb(err)
      // inspect or mutate the socket here
      cb(null, socket)
    })
  },
})

H2CClient

H2CClient is a specialised Client variant that enforces HTTP/2 cleartext (h2c) over plain TCP — no TLS required. It accepts the same options as Client except those specific to TLS negotiation.
H2CClient only supports the http: protocol. Use it when the server speaks HTTP/2 over a plain connection (no TLS). For HTTP/2 over TLS, use Client with allowH2: true.
H2CClient basic usage
import { H2CClient } from 'undici'

const client = new H2CClient('http://localhost:3000')

const { statusCode, body } = await client.request({
  path: '/',
  method: 'GET',
})

console.log(statusCode) // 200
console.log(await body.text()) // Hello, world!

await client.close()
H2CClient supports the same maxConcurrentStreams, pingInterval, headersTimeout, bodyTimeout, keepAliveTimeout, keepAliveMaxTimeout, pipelining, strictContentLength, and connect options as Client.

Build docs developers (and LLMs) love