Standard library / net · on the one-page reference

net

Experimental — new, manually tested rather than conformance-suite covered.

Raw TCP sockets — the layer http's own client/server are already built on, exposed directly for protocols that aren't HTTP. No TLS (matching Node's own split between net and tls).

net.connect(host, port) Wasm: limited

(string, int) → Socket — blocking connect, real DNS resolution for hostnames (via the same std.Io.net.HostName.connect path Lumen's own http.request client already uses internally to reach a hostname, not a new, unverified code path) as well as literal IPs. A failed connect (refused, unknown host, timeout) doesn't throw — it degrades to a Socket whose .read() always returns "" and .write() is a no-op, the same "fallback, don't crash" convention fs.createReadStream already established for a missing file.

const sock: Socket = net.connect("127.0.0.1", 9301);
sock.write("hello\n");
console.log(sock.read());
sock.close();
net.createServer(port, handler) Wasm: limited

(int, (Socket) → void) → void — accepts connections forever, never returns. Unlike http.createServer's (HttpRequest) → HttpResponse handler (a call-and-return shape that fits HTTP's own framing), a raw TCP handler gets the Socket itself and drives it in whatever order its own protocol needs. The socket is closed automatically once handler returns, whether or not the handler already called .close() itself (idempotent, no double-close error) — a handler that forgets to close won't leak the connection for the life of the server.

function handleConn(sock: Socket): void {
  const line = sock.read();
  sock.write("echo:" + line);
}

net.createServer(9301, handleConn);

Single connection at a time, unlike http.createServer's thread-pool-backed concurrency: nothing analogous has been benchmarked yet for a raw-bytes protocol with no request/response cadence to measure against, so a slow or long-lived handler blocks new connections from being accepted until it returns. The same worker-thread-pool mechanism http.createServer already uses is a direct, mechanical extension here later; not attempted this pass so the Socket type itself stayed the focus of this slice.

Socket.read()

() → string — the next chunk (bounded by a fixed 64KB internal buffer, matching ReadableStream.read()'s exact convention). "" at EOF, on a closed socket, or on a socket that never connected — a real empty chunk and end-of-stream are indistinguishable here, the same simplification Streams (spec 046) already documented and accepted.

Socket.write(chunk)

string → void — writes and flushes immediately on every call, unlike WritableStream.write() (which defers flushing to .close()): a long-lived socket conversation has no single "I'm done" moment the way a one-shot file write does, so buffering until some later .close() could mean the peer never sees the bytes in time. No-op on a closed or never-connected socket.

Socket.close()

() → void — closes the underlying connection. Safe to call more than once, or on a socket that never connected.