js/net/quic

js/net/quic/index.ts

fino:net/quic — low-level QUIC client and server endpoints.

Learn more:

This module exposes QUIC as an EventTarget-first transport API. A QuicEndpoint owns one or more UDP listeners and delivers accepted connections through both connection events and the pull-based accept() method. Each QuicConnection similarly delivers incoming streams through stream events and acceptStream().

Streams expose Web Streams as the primary public interface: QuicStream.readable and QuicStream.writable move Uint8Array chunks. The lower-level reader and writer properties expose Fino byte reader and writer objects for code that needs direct structural reads or explicit write control.

This is intentionally transport-level only and does not implement HTTP/3 or WebTransport. Endpoints advertise h3 by default so callers can build raw HTTP/3-compatible transports, but no fino:net/http integration is performed here. QUIC DATAGRAM and controlled key updates are exposed for lower protocol work. Replay-sensitive features such as 0-RTT stay disabled unless callers explicitly provide the required policy and storage.

Release verification has required and gated lanes. Local QUIC loopback and simulator tests are required for release builds. External ngtcp2 HQ interop, Node QUIC interop via NODE_QUIC_BIN, and the loopback throughput benchmark are gated lanes: they run when the corresponding tools or baseline binaries are configured and otherwise skip explicitly.

Deferred advanced scope remains visible but is not a release blocker: Node DATAGRAM interop parity still depends on Node's experimental API shape, resumed-session external interop is not proven by NODE_QUIC_BIN, and active migration/version-negotiation external interop depends on peer tooling. Backend-specific TLS constraints are explicit release scope: OpenSSL-only SNI context and TLS group controls are tested, while GnuTLS parity for those controls is deferred.

import { QuicEndpoint } from 'fino:net/quic';

const endpoint = new QuicEndpoint({ alpnProtocols: ['h3'] });
const listener = await endpoint.listen({
  address: { family: 'ipv4', ip: '127.0.0.1', port: 4433 },
});

endpoint.addEventListener('connection', async (event) => {
  const stream = await event.connection.acceptStream();
  await stream.writer.write(new TextEncoder().encode('ok'));
});

await listener.close();
await endpoint.close();

Constants

const cryptoBackend

Re-exported from availability.cryptoBackend.

const quicAvailable

Re-exported from availability.quicAvailable.

const quicResetStreamAtAvailable

Re-exported from availability.quicResetStreamAtAvailable.

const quicVersion: string | null

Re-exported from availability.quicVersion.

Functions

function requireQuic(): void

Re-exported from availability.requireQuic.

Classes

class QuicConnection extends EventTarget {

Re-exported from js/net/quic/connection.QuicConnection.

class CidRoutingTable<T = QuicConnection> {

Re-exported from js/net/quic/endpoint.CidRoutingTable.

class QuicEndpoint extends EventTarget {

Re-exported from js/net/quic/endpoint.QuicEndpoint.

class QuicConnectionEvent extends Event {

Re-exported from events.QuicConnectionEvent.

class QuicDatagramEvent extends Event {

Re-exported from events.QuicDatagramEvent.

class QuicDatagramStatusEvent extends Event {

Re-exported from events.QuicDatagramStatusEvent.

class QuicEarlyDataEvent extends Event {

Re-exported from events.QuicEarlyDataEvent.

class QuicErrorEvent extends Event {

Re-exported from events.QuicErrorEvent.

class QuicNewTokenEvent extends Event {

Re-exported from events.QuicNewTokenEvent.

class QuicPathValidationEvent extends Event {

Re-exported from events.QuicPathValidationEvent.

class QuicStopSendingEvent extends Event {

Re-exported from events.QuicStopSendingEvent.

class QuicStreamBlockedEvent extends Event {

Re-exported from events.QuicStreamBlockedEvent.

class QuicStreamEvent extends Event {

Re-exported from events.QuicStreamEvent.

class QuicStreamResetEvent extends Event {

Re-exported from events.QuicStreamResetEvent.

class QuicVersionNegotiationError extends Error {

Re-exported from events.QuicVersionNegotiationError.

class QuicListener {

Re-exported from js/net/quic/listener.QuicListener.

class QuicStream extends EventTarget {

Re-exported from js/net/quic/stream.QuicStream.

Types

type QuicConnectionOptions = { handshakeTimeoutMs?: number; initialRttMs?: number; keepAliveTimeoutMs?: number; maxPayloadSize?: number; maxWindow?: number; maxStreamWindow?: number; unacknowledgedPacketThreshold?: number; congestionControl?: 'cubic' | 'reno' | 'bbr'; drainingPeriodMultiplier?: number; streamIdleTimeoutMs?: number; maxIdleTimeoutMs?: number; initialMaxData?: number; initialMaxStreamDataBidiLocal?: number; initialMaxStreamDataBidiRemote?: number; initialMaxStreamDataUni?: number; initialMaxStreamsBidi?: number; initialMaxStreamsUni?: number; activeConnectionIdLimit?: number; maxAckDelayMs?: number; ackDelayExponent?: number; disableActiveMigration?: boolean; cidLength?: number; }

Re-exported from js/net/quic/connection.QuicConnectionOptions.

type QuicConnectionState = 'connecting' | 'connected' | 'closing' | 'closed'

Re-exported from js/net/quic/connection.QuicConnectionState.

type QuicConnectionStats = { readonly createdAt: number; readonly connectedAt: number | null; readonly handshakeConfirmedAt: number | null; readonly closingAt: number | null; readonly destroyedAt: number | null; readonly bytesReceived: number; readonly bytesSent: number; readonly packetsReceived: number; readonly packetsSent: number; readonly datagramsReceived: number; readonly datagramsSent: number; readonly datagramsAcked: number; readonly datagramsLost: number; readonly datagramsAbandoned: number; readonly streamsOpened: number; readonly streamsReceived: number; readonly bidiIncomingStreams: number; readonly bidiOutgoingStreams: number; readonly uniIncomingStreams: number; readonly uniOutgoingStreams: number; readonly streamsClosed: number; readonly maxBytesInFlight: number; readonly bytesInFlight: number; readonly blockCount: number; readonly congestionWindow: number; readonly latestRttMs: number; readonly minRttMs: number; readonly rttVarianceMs: number; readonly smoothedRttMs: number; readonly slowStartThreshold: number; readonly packetsLost: number; readonly bytesLost: number; readonly pingReceived: number; readonly packetsDiscarded: number; readonly streamsIdleTimedOut: number; readonly pendingWriteBytes: number; readonly outstandingStreamBytes: number; readonly qlogOpenFailed: number; readonly qlogWriteFailed: number; }

Re-exported from js/net/quic/connection.QuicConnectionStats.

type QuicPeerVerification = { verified: boolean; errorCode: number; reason: string | null; }

Re-exported from js/net/quic/connection.QuicPeerVerification.

type QuicTransportParameterSnapshot = { readonly initialMaxStreamDataBidiLocal: number; readonly initialMaxStreamDataBidiRemote: number; readonly initialMaxStreamDataUni: number; readonly initialMaxData: number; readonly initialMaxStreamsBidi: number; readonly initialMaxStreamsUni: number; readonly maxIdleTimeoutMs: number; readonly maxUdpPayloadSize: number; readonly activeConnectionIdLimit: number; readonly ackDelayExponent: number; readonly maxAckDelayMs: number; readonly maxDatagramFrameSize: number; readonly disableActiveMigration: boolean; readonly preferredAddress: QuicAddress | null; readonly originalDestinationConnectionId: Uint8Array | null; readonly initialSourceConnectionId: Uint8Array | null; readonly retrySourceConnectionId: Uint8Array | null; readonly statelessResetToken: Uint8Array | null; }

Re-exported from js/net/quic/connection.QuicTransportParameterSnapshot.

type QuicSNIContextOptions = { certificateFile: string; privateKeyFile: string; alpnProtocols?: string[]; tlsGroups?: string[]; clientAuth?: 'none' | 'request' | 'require'; verifyClient?: boolean; rejectUnauthorized?: boolean; ca?: QuicCaOptions; }

Re-exported from js/net/quic/listener.QuicSNIContextOptions.

type QuicStreamStats = { readonly createdAt: number; readonly openedAt: number | null; readonly receivedAt: number | null; readonly ackedAt: number | null; readonly destroyedAt: number | null; readonly bytesReceived: number; readonly bytesSent: number; readonly bytesAcked: number; readonly finalSize: number | null; readonly maxOffset: number; readonly maxOffsetAcked: number; readonly maxOffsetReceived: number; readonly maxOffsetSent: number; readonly bytesAccumulated: number; readonly maxBytesAccumulated: number; }

Re-exported from js/net/quic/stream.QuicStreamStats.

type QuicAddress = { family: 'ipv4' | 'ipv6'; ip: string; port: number; }

Re-exported from js/net/quic/types.QuicAddress.

type QuicCaOptions = { file?: string; directory?: string; pem?: string | Uint8Array | Array<string | Uint8Array>; }

Re-exported from js/net/quic/types.QuicCaOptions.

type QuicDatagramOptions = { enabled?: boolean; maxFrameSize?: number; maxPending?: number; dropPolicy?: 'drop-oldest' | 'drop-newest'; maxSendAttempts?: number; }

Re-exported from js/net/quic/types.QuicDatagramOptions.

type QuicDatagramStatus = 'ack' | 'lost' | 'abandoned'

Re-exported from js/net/quic/types.QuicDatagramStatus.

type QuicEarlyDataPolicy = { replaySafe: true; maxBytes?: number; }

Re-exported from js/net/quic/types.QuicEarlyDataPolicy.

type QuicEndpointStats = { createdAt: number; destroyedAt: number | null; packetsReceived: number; packetsSent: number; bytesReceived: number; bytesSent: number; packetsBlocked: number; sourceBlockedPackets: number; serverBusyCount: number; connectionLimitPackets: number; retrySent: number; retryRateLimited: number; retryTokenAccepted: number; retryTokenRejected: number; addressTokenAccepted: number; addressTokenRejected: number; versionNegotiationSent: number; versionNegotiationRateLimited: number; statelessResetSent: number; statelessResetRateLimited: number; immediateCloseSent: number; immediateCloseRateLimited: number; sessionCreationRateLimited: number; serverConnections: number; clientConnections: number; activeServerConnections: number; activeConnections: number; }

Re-exported from js/net/quic/types.QuicEndpointStats.

type QuicKeylogOptions = false | { path: string; }

Re-exported from js/net/quic/types.QuicKeylogOptions.

type QuicMigrationOptions = { enabled?: boolean; preferredAddress?: QuicPreferredAddressOptions; usePreferredAddress?: boolean; }

Re-exported from js/net/quic/types.QuicMigrationOptions.

type QuicPath = { localAddress: QuicAddress; remoteAddress: QuicAddress; }

Re-exported from js/net/quic/types.QuicPath.

type QuicPathValidationResult = 'success' | 'failure' | 'aborted'

Re-exported from js/net/quic/types.QuicPathValidationResult.

type QuicQlogOptions = false | { path?: string; events?: string[]; }

Re-exported from js/net/quic/types.QuicQlogOptions.

type QuicRateLimitOptions = false | { rate?: number; burst?: number; }

Re-exported from js/net/quic/types.QuicRateLimitOptions.

type QuicResolvedConnectionOptions = { readonly handshakeTimeoutMs: number; readonly initialRttMs: number; readonly keepAliveTimeoutMs: number; readonly maxPayloadSize: number; readonly maxWindow: number; readonly maxStreamWindow: number; readonly unacknowledgedPacketThreshold: number; readonly congestionControl: 'cubic' | 'reno' | 'bbr'; readonly drainingPeriodMultiplier: number; readonly streamIdleTimeoutMs: number; readonly cidLength: number; }

Re-exported from js/net/quic/types.QuicResolvedConnectionOptions.

type QuicResolvedRateLimitOptions = { readonly rate: number; readonly burst: number; }

Re-exported from js/net/quic/types.QuicResolvedRateLimitOptions.

type QuicResolvedSourceAddressOptions = { readonly allow: readonly string[] | null; readonly deny: readonly string[]; }

Re-exported from js/net/quic/types.QuicResolvedSourceAddressOptions.

type QuicResolvedTransportOptions = { readonly busy: boolean; readonly maxConnections: number; readonly maxConnectionsPerRemoteAddress: number; readonly sourceAddress: QuicResolvedSourceAddressOptions; readonly retryTokenTimeoutMs: number; readonly addressTokenTimeoutMs: number; readonly addressValidationCacheSize: number; readonly retryRateLimit: QuicResolvedRateLimitOptions; readonly versionNegotiationRateLimit: QuicResolvedRateLimitOptions; readonly statelessResetRateLimit: QuicResolvedRateLimitOptions; readonly immediateCloseRateLimit: QuicResolvedRateLimitOptions; readonly sessionCreationRateLimit: QuicResolvedRateLimitOptions; readonly disableStatelessReset: boolean; readonly ecn: boolean; }

Re-exported from js/net/quic/types.QuicResolvedTransportOptions.

type QuicRetryOptions = false | { enabled: boolean; tokenSecret?: Uint8Array; }

Re-exported from js/net/quic/types.QuicRetryOptions.

type QuicSessionState = { ticket?: Uint8Array; addressToken?: Uint8Array; transportParameters?: Uint8Array; earlyDataMax?: number; version?: QuicVersion; expiresAt?: number; }

Re-exported from js/net/quic/types.QuicSessionState.

type QuicSocketOptions = { ipv6Only?: boolean; reusePort?: boolean; receiveBufferSize?: number; sendBufferSize?: number; ttl?: number; }

Re-exported from js/net/quic/types.QuicSocketOptions.

type QuicSourceAddressOptions = { allow?: string[]; deny?: string[]; }

Re-exported from js/net/quic/types.QuicSourceAddressOptions.

type QuicTlsCipherSuite = 'TLS_AES_128_GCM_SHA256' | 'TLS_AES_256_GCM_SHA384' | 'TLS_CHACHA20_POLY1305_SHA256'

Re-exported from js/net/quic/types.QuicTlsCipherSuite.

type QuicTransportOptions = { busy?: boolean; maxConnections?: number; maxConnectionsPerRemoteAddress?: number; sourceAddress?: QuicSourceAddressOptions; retryTokenTimeoutMs?: number; addressTokenTimeoutMs?: number; addressValidationCacheSize?: number; retryRateLimit?: QuicRateLimitOptions; versionNegotiationRateLimit?: QuicRateLimitOptions; statelessResetRateLimit?: QuicRateLimitOptions; immediateCloseRateLimit?: QuicRateLimitOptions; sessionCreationRateLimit?: QuicRateLimitOptions; disableStatelessReset?: boolean; ecn?: boolean; }

Re-exported from js/net/quic/types.QuicTransportOptions.

type QuicVersion = 'v1' | 'v2'

Re-exported from js/net/quic/types.QuicVersion.

Interfaces

interface QuicListenOptions {

Re-exported from js/net/quic/listener.QuicListenOptions.

interface QuicConnectOptions {

Re-exported from js/net/quic/types.QuicConnectOptions.

interface QuicEndpointOptions {

Re-exported from js/net/quic/types.QuicEndpointOptions.

interface QuicSessionStore {

Re-exported from js/net/quic/types.QuicSessionStore.