Skip to content

TCP sockets

connect() is imported from cloudflare:sockets for outbound TCP. The API shape matches Cloudflare TCP sockets. The network policy boundary does not.

ts
import { connect } from "cloudflare:sockets";

export default {
  async fetch(request: Request): Promise<Response> {
    const socket = connect({ hostname: "example.com", port: 80 });
    const writer = socket.writable.getWriter();
    await writer.write(new TextEncoder().encode("GET / HTTP/1.0\r\n\r\n"));
    await writer.close();
    return new Response(socket.readable, { headers: { "Content-Type": "text/plain" } });
  },
} satisfies ExportedHandler;

Full Socket / SocketAddress / SocketOptions / startTls() signatures: Cloudflare TCP sockets. Do not create a socket in global scope and share it across requests.

Compatibility

TopicCloudflareopen-compute
connect(address, options?) returns a Socket with readable / writable / opened / closed / close() / startTls()YesYes
secureTransport: off | on | starttlsYesYes
Tenant general outbound fetch(), cloudflare:sockets.connect(), node:netCloudflare hosted network policyShare one stock-workerd Network(allow=["public"])
Named Service/DO Fetcher.connect()Hosted policyUses the declared capability tunnel; not a second general outbound
Cloudflare-owned IP-range block / Worker self-connect (TCP Loop) / default SMTP port 25 prohibitionYes — troubleshootingNot provided
Private / loopback / link-local / metadata / UnixRejectedRejected by the public address layer