Skip to main content
Bun provides low-level TCP and UDP APIs for performance-sensitive networking where HTTP overhead is undesirable — think database clients, game servers, or custom protocols.
These are low-level APIs intended for library authors and advanced use cases. For most applications, prefer Bun.serve() (HTTP) or fetch().

TCP server with Bun.listen()

All event handlers are declared once per server and shared across all connections — this avoids garbage-collector pressure from per-socket closures and keeps memory usage flat.

Attaching data to a socket

Attach contextual data to each socket in the open handler. Access it via socket.data in any handler.

Stopping a TCP server


TCP echo server (complete example)

1

Create the server

server.ts
2

Create the client

client.ts

TCP client with Bun.connect()

Bun.connect() supports the same socket handlers as Bun.listen() plus three client-specific ones:

TLS over TCP

TLS server

key and cert accept a string, BunFile, Buffer, TypedArray, or an array of any of those.

TLS client


Hot reloading

Both servers and individual sockets support hot-swapping their handlers at runtime without dropping connections:

Buffering TCP writes

TCP sockets in Bun do not automatically buffer writes. Many small socket.write() calls perform significantly worse than a single larger one. Use ArrayBufferSink to accumulate data before flushing:

UDP with Bun.udpSocket()

UDP is connectionless and lower latency than TCP. It is suited for real-time applications like voice chat, gaming, or DNS clients where occasional packet loss is acceptable.

Create a UDP socket

Send a datagram

send() requires a resolved IP address. It does not perform DNS lookups in order to keep latency as low as possible.

Receive datagrams

Connected UDP socket

Connecting a UDP socket binds it to a single peer — all sends go to that peer and only packets from that peer are received. This can also improve performance on some operating systems.

Batch sends with sendMany()

Amortize the system-call cost when sending many datagrams at once:
sendMany() returns the number of packets successfully sent.

Backpressure

When the OS packet buffer is full, send() returns false and sendMany() returns fewer packets than requested. The drain handler fires when the socket is writable again:

Socket options

Multicast

Source-specific multicast (SSM):