This is a high-performance, event notification library for Nim. It provides a low-level event loop and timer wheel, as well as higher-level abstractions for building TCP/UDP, HTTP and WebSocket servers.
The library is designed to be minimal and efficient, with a focus on low-latency event handling and minimal overhead, providing a solid foundation for building high-performance networked applications in Nim.
Features
Core Event Loop (loop.nim)
- Single-threaded non-blocking reactor
- I/O multiplexing via kqueue (macOS/BSD), epoll (Linux), IOCP (Windows), poll (fallback), or the opt-in Linux io_uring backend (io/)
- 4-level hierarchical timer wheel — O(1) insert/fire/cancel
- One-shot and repeating interval timers
- Deferred callbacks (executed before each I/O poll iteration)
- Idle handlers (executed when no I/O events are pending)
- Pointer-based fd watcher dispatch — zero hash-table lookups on the hot path
- Generation-counter stale event detection
- Dead watcher sweep with zombie/retired list for in-flight event safety
- Thread-safe stop() via eventfd (Linux) or self-pipe (macOS/BSD)
- Buffer pool for shared read buffers
- Adaptive event capacity scaling (min 64, max 4096)
TCP Networking (net/tcp.nim)
- Non-blocking TCP server with connection pooling
- Non-blocking TCP client with async connect (DNS resolved on the loop)
- Edge-triggered I/O events
- Write buffering with automatic corking (TCP_CORK / TCP_NOPUSH)
- Scatter-gather writes via writev
- Zero-copy file send via sendfile (Linux sendfile, macOS sendfile, POSIX fallback)
- Graceful shutdown with close-after-drain (closeAfterDrain)
- Unix domain socket support (macOS/BSD/Linux)
- SO_LINGER{0} for fast shutdown
- Per-connection read buffer pooling
Async DNS (net/dns.nim)
- In-loop DNS resolver (RFC 1035) — no blocking getaddrinfo, no worker threads
- Reads /etc/hosts and /etc/resolv.conf (system resolver config)
- A + AAAA queries with A-fallback; retries with timeout/attempts
- TTL-based result cache + negative caching
- resolveAddrAsync for users; connect uses it automatically
- Numeric IP literals resolve inline (zero DNS I/O)
OS Signals (signal.nim)
- In-process SignalRelay pub/sub bus (listen / listenOnce / unlisten)
- watchOsSignal/watchOsSignals deliver real OS signals through the loop
- OsSignal enum: SIGHUP, SIGINT, SIGQUIT, SIGUSR1/2, SIGPIPE, SIGALRM, SIGTERM, SIGURG, SIGCHLD, SIGIO
- Platform-native delivery: signalfd (Linux), self-pipe (macOS/BSD/POSIX), SetConsoleCtrlHandler Ctrl+C (Windows) — no global signal handlers
- Graceful shutdown on SIGINT/SIGTERM without blocking the loop
Stream I/O (stream.nim)
- IoStream wraps an arbitrary non-blocking fd and drives it from the loop
- Pipes, subprocess stdout, UDS and socketpair IPC; newStreamPair creates a full-duplex channel
- Connection-style write path: direct write drained until EAGAIN, remainder buffered and flushed on Write events; 32 MiB queued-write cap
- pause/resume read backpressure (a paused reader blocks the pipe writer)
- close is the single terminal transition and fires onClose exactly once; closeAfterWrite flushes then delivers EOF to the peer
- POSIX only (Windows IOCP is sockets-only); regular files work on kqueue but epoll rejects them
UDP Networking (net/udp.nim)
- Non-blocking UDP server (bind) and client (connect)
- recvfrom / sendto for connectionless communication
- Connected UDP sockets for peer-scoped send/recv
HTTP/1.1 Parser (proto/http.nim)
- Incremental, zero-copy parser — materialize strings lazily from byte offsets
- O(1) method dispatch via first-byte switch
- Pipelined request support
- Streaming body handling via callback
- Chunked transfer encoding
- Body streaming to file
- Multipart form data support
HTTP Server (proto/httpserver.nim)
- Implement your-own-router — lower-level callback-based design
- OnRequestCallback* = proc(req: HttpRequest, res: HttpResponse) {.gcsafe.}
- Higher-level frameworks implement routing on top of this callback
- Streaming response body
- Static file serving with MIME type detection
- Conditional requests (If-Modified-Since, If-None-Match)
- Range requests with 206 Partial Content
- Directory listing
- CORS headers
- Streaming multipart upload handling
- Pipelined request-response processing
WebSocket (proto/ws.nim)
- RFC 6455 compliant
- Standalone WebSocket server mode
- HTTP upgrade from HttpServer routes
- Text, binary, ping/pong, and close frames
- Per-message deflate extension
- Masked frame handling
Multi-threaded HTTP Server (proto/multithread.nim)
- SO_REUSEPORT kernel-level connection distribution
- One event loop + listen socket per worker thread
- Zero cross-thread communication — no single-threaded acceptor bottleneck
- Graceful shutdown via shutdown pipe
SIMD-Accelerated Scanning (proto/simdscan.nim)
- SSE2-accelerated CRLF detection
- Scalar fallback for non-x86 architectures
Platform Abstraction (platform/)
- kqueue — macOS/BSD (high-performance, edge-triggered)
- epoll — Linux (with eventfd wake)
- iocp — Windows (I/O Completion Ports)
- poll — POSIX fallback
- io/ — Linux io_uring backend (submission-based, opt-in). Enabled with nimble --features:io_uring <cmd>, requires "powpow[io_uring]", or nim c -d:powpowIoUring. The same public API, driven by IORING_OP_ACCEPT/RECV/SEND/CONNECT/SEND_ZC/SPLICE/... completions instead of readiness events; the generic fd-watcher API is emulated with one-shot IORING_OP_POLL_ADD. Ships the full io_uring API binding (io/uring.nim), IORING_REGISTER_PROBE feature detection, zero-copy SEND_ZC and SPLICE file sends, and registered buffers (IORING_REGISTER_BUFFERS). Requires Linux >= 5.6.
Networking Common (net/common.nim)
- Platform-agnostic socket API and address resolution (IPv4 + IPv6)
- Socket options: non-blocking, SO_REUSEADDR, SO_REUSEPORT, TCP_NODELAY
- sendfile zero-copy file transmission
- Cross-platform error handling (EAGAIN, EINPROGRESS, etc.)
- Auto-initialization (WSAStartup on Windows, SIGPIPE ignore on POSIX)
Exports
-
==, TimerCallback, HttpConnect, HttpPatch, HttpGet, HttpHead, EventType, FdCallback, TimerId, HttpPost, HttpTrace, HttpMethod, HttpPut, HttpOptions, TlsState, HttpDelete, ObserverCallback, Callback, iouEnabled, modify, ensureCapacity, HttpConnect, HttpPatch, ==, HttpGet, HttpHead, HttpPost, HttpMethod, FdCallback, remove, add, TimerCallback, EventType, HttpPut, PlatformEvent, HttpOptions, TlsState, TimerId, HttpDelete, HttpTrace, Platform, init, poll, ObserverCallback, Callback, wake, iouEnabled, addIdle, HttpConnect, pollWallSec, removeIdle, HttpGet, timerCount, releaseBuf, HttpPost, EventType, addCleanup, close, remove, pollNowMs, add, unregisterFd, HttpTrace, ==, deferCall, observe, addTimer, PlatformEvent, HttpOptions, TlsState, ensureCapacity, init, modify, FdWatcher, addInterval, runOnce, close, poll, wake, iouEnabled, Observer, unregister, TimerId, HttpPatch, monoMs, modify, acquireBuf, HttpHead, run, register, postToLoop, newLoop, HttpDelete, FdCallback, TimerCallback, poll, HttpMethod, HttpPut, resumeTimer, addTurnEndHook, pauseTimer, Loop, Platform, isRunning, cancelTimer, ObserverCallback, Callback, cancelObserver, stop, addIdle, sockInProgress, DtlsMaxChunk, HttpGet, FdCallback, addInterval, close, timerCount, bindUdp, HttpPost, observe, sendv, monoMs, HttpPut, SEEK_END, TxtCallback, DnsResolver, shutdown, remove, setTcpNoDelay, MaxConnPoolSize, sockWritev, OnUdpData, closeFile, close, close, setAlpnProtocols, sockaddrFromIp, HttpTrace, addTimer, maxBufPoolSize, sendFile, DtlsConfig, HttpOptions, HttpDelete, TlsState, IoStream, Platform, write, readFile, sockRecv, driveHandshake, connectUdp, sendTo, lastSocketError, O_BINARY, O_RDONLY, closeDns, unregisterFd, DtlsMtuDefault, sessionCount, close, wrapTls, OnAccept, Observer, closeAfterSend, DnsCacheEntry, send, ConnState, listenUnix, send, unregister, TimerId, IoStreamState, addCleanup, sockWouldBlock, newClientTlsContext, HttpHead, connectUnix, injectFd, close, removeIdle, close, setReuseAddr, sendTo, SslError, newServerTlsContext, tlsRead, run, getClientSockAddr, newTcpServer, postToLoop, isTlsActive, flushWriteBuffer, MxCallback, TimerCallback, sendFileActive, FdWatcher, acquireBuf, MaxIoStreamWriteBuffer, cancelObserver, newDtlsServer, resumeTimer, closeAfterDrain, addTurnEndHook, closeAndRelease, sockShutdown, cancelSendFile, DtlsSweepIntervalDefaultMs, ==, tlsFree, DefaultSendFileChunk, SEEK_CUR, sendTo, maxWriteBufferSize, newServerDtlsContext, Callback, DtlsError, OnError, SendFileChunkSize, newStreamPair, resume, releaseBuf, OnData, openStream, listen, openFileRead, connectDtls, HttpConnect, pollWallSec, DtlsSession, sockSend, resolveAddr, EventType, getSockLen, continueSendFile, DtlsMaxSessionsDefault, connectHe, close, setReusePort, pollNowMs, close, UNIX_PATH_MAX, MaxBufPoolSize, TxtRecord, write, DtlsRole, DtlsSessionState, deferCall, send, newConnection, setTcpCork, resolveMxAsync, ensureCapacity, setNonBlocking, finCloseNow, OnClose, init, SslContext, alpnSelected, initNet, runOnce, isIpAddress, UdpSocket, sendFileChunk, Connection, Loop, configureDns, peerAddrStr, wake, sockInterrupted, resolveTxtAsync, iouEnabled, add, send, DnsCallback, connect, sendTo, DtlsContext, register, setDnsServers, modify, seekFile, HttpPatch, setIpv6Only, pause, newLoop, DtlsServer, maxConnPoolSize, poll, resolveAddrBothAsync, closeAfterWrite, tlsWrite, ResolvedIp, getClientIp, poll, formatIp, defaultDtlsConfig, ObserverCallback, resolveAddrAsync, getFileSize, sendTo, TlsRole, HttpMethod, resolveAddrAll, TcpServer, SEEK_SET, DefaultBufSize, MxRecord, pauseTimer, DnsQuery, send, newClientDtlsContext, NetError, DtlsHandshakeTimeoutDefaultMs, modify, DtlsIdleTimeoutDefaultMs, sockClose, isRunning, send, PlatformEvent, cancelTimer, stop, H2ConnectionPreface, shutdown, withinRoot, isComplete, HttpRequest, onMessage, TcpServer, reset, WsErrorCb, writeFrameMasked, options, huffmanEncodeInto, h2Draining, sendPong, close, decode, releaseBuf, stageFrame, encodeFrameInto, removeSession, header, drainChunk, getConn, post, post, start, addIdle, onData, peekMethod, sendMessage, WsCloseCb, encodeWindowUpdate, modify, H2ClientConn, encodeIntInto, listen, setError, newWsServer, H2Role, head, start, H2DefaultMaxConcurrent, HttpConnect, status, unregisterFd, pollWallSec, DefaultChunkSize, reset, removeIdle, HttpOptions, sendError, HttpGet, options, getTrailers, idleConnections, close, timerCount, headersDone, getBodyStream, stageFrame, HttpError, close, HttpPost, HttpMethod, H2FrameHeaderLen, connectH2Tls, sendHandshakeRequest, continueSendFile, sendv, header, peekContentType, listenUnix, push, connectHe, decodeInt, request, getStatusText, newProxyServer, isRunning, start, WsConnection, getClientIp, initHuffman, OnH2RequestCallback, remove, post, start, sendMessage, DefaultIdleTimeoutMs, newMultiRateLimiter, ProxyDir, start, OnData, newH2ClientPool, OnProxyData, getBodyView, MaxConnPoolSize, H2MaxFrameSizeMin, pollNowMs, encodeStringInto, MaxRequestLine, closeWs, addCleanup, setMaxPending, startClientPreface, DefaultMaxIdlePerHost, close, getMultipart, put, close, getConnectionClose, feed, OnProxyClose, appendBytes, put, resetForNext, MaxWsPoolSize, MaxBufPoolSize, stop, getLoop, H2SendBufCap, idleConnectionsFor, error, pendingBytes, isOk, H2Conn, phase, close, decodePing, listen, request, encodeSettings, H2ClientPool, add, onUpstreamData, send, get, emptyH2Body, observe, encodeData, addTimer, setKeepAliveTimeout, flushStagedH2, listen, connectUnix, setMaxTableSize, maxBufPoolSize, sendFile, newConnection, request, getBody, request, OnRequestCallback, patch, OnError, PlatformEvent, newLoop, H2Server, HttpDelete, TlsState, getLoop, MaxHeaders, WindowLimit, getTrailer, markSent, newProxyServer, ensureCapacity, streamFile, getContentLength, isChunked, head, patch, listen, finCloseNow, hasTrailers, Platform, onClose, init, H2DefaultWindowSize, run, listen, modify, start, driveHandshake, OnProxyUpstreamConnect, PoolKey, FdWatcher, H2FlagEndStream, status, sendBinary, getRemainingData, getBodyString, post, H2FrameType, runOnce, H2FlagPadded, decodeString, readChunk, tlsRead, ensureTcpServer, head, openClientStream, decodeGoaway, tryAdvance, onConnect, start, encode, poll, setUpstreamUnix, connectH2, encodeInto, getLoop, onClose, decodeSettings, H2Frame, encodeFrame, close, check, request, encodePing, wake, getBody, newHttpServer, OnAccept, getStatusCode, iouEnabled, wsPoolPop, parseRange, Observer, HpackDefaultTableSize, closeAfterSend, H2Request, setUpstream, serveStatic, getStatusCode, newAsyncHttpClient, peekPath, send, DefaultMaxFrameSize, flushSendBuf, newHttpClient, send, get, MaxHeaderSize, HttpResponse, readChunkInto, newH2Server, ParsePhase, H2ClientResponse, isBytesUnit, parseWsFrames, ConnState, WsMessageCb, connect, websocketUpgrade, H2Response, MultiThreadHttpServer, HttpClientResponse, PooledConn, H2DefaultMaxHeaderList, patchFrameHeader, encodeHeaders, pauseTimer, send, RateLimiter, unregister, ProxyServer, TimerId, put, get, close, listen, getTrailer, sendPing, request, options, populatePools, writeFrame, getPath, stop, removeFromPool, headerBytes, delete, getRequest, H2ErrorCode, addConnection, HpackError, getHeaders, HttpPatch, options, H2FlagEndHeaders, monoMs, ==, getMethod, acquireBuf, listen, HttpHead, getTrailers, newWsServer, ConnHttp, wsPoolAdd, H2ClientCallback, writeDisposition, computeAcceptKey, idleConnections, close, streamToFile, h2Closed, newRateLimiter, sendFile, DefaultBodyBuf, start, maxConnPoolSize, close, hasTrailers, resolveReal, onUpstreamConnect, start, getFileExt, getHeaders, peekChunk, peekAll, HpackMaxStringLen, HttpServer, close, H2StreamState, run, isError, reset, H2FlagPriority, FdCallback, H2FrameParser, MaxStreamBodySize, encodePingAck, isEstablished, newHttpConnPool, tcpServer=, getBody, ProxyPair, encodeGoaway, encodeString, delete, DefaultKeepAliveMs, HpackHeader, encodeSettingsAck, newTcpServer, Connection, newH2Conn, onOpen, postToLoop, close, getClientSockAddr, allow, tlsWrite, getHttpMinor, getClientIp, flushWriteBuffer, sendText, sendHandshake, getBodyString, newHttpParser, WsError, MultiThreadH2Server, H2Setting, injectFd, huffmanDecode, getConnectionClose, getQuery, upgradeToWs, newHttpServer, closeAll, H2MaxWindowSize, request, formatIp, getConnectionClose, connectWs, decodeRstStream, TimerCallback, H2Error, newWsConnection, ObserverCallback, HttpClientBase, sendFileActive, close, getClientIp, WsServer, H2MaxFrameSizeMax, serveFile, H2FlagAck, H2SettingsId, start, feedH2, stop, HpackContext, WsFrameKind, close, readChunkString, DefaultMaxPending, teardownByUpstreamFd, frameTypeFromInt, register, getUrl, poll, getContentLength, OnProxyError, EventType, tcpServer, listenUnix, head, encodeInt, HttpPut, H2DefaultMaxBody, resumeTimer, listenUnix, HttpParser, closeAfterDrain, addTurnEndHook, buildHandshakeResponse, decodeWindowUpdate, closeAndRelease, HttpTrace, put, patch, HpackStaticTableLen, get, listen, send, getHeaderValue, request, getProtocol, parseWsUrl, getStatusText, getContentLength, patch, deferCall, cancelSendFile, Loop, addInterval, DefaultMaxIdleTotal, WsOpenCb, DefaultMaxResponseBody, HttpClient, OnClose, onError, finalizeCloseDelimited, setMaxConnections, decodePriority, ensureH2FlushHook, newH2FrameParser, newProxyServer, tlsFree, listen, OnProxyConnect, delete, getHeaderValue, start, newMultiThreadH2Server, start, getHeaders, close, cancelTimer, MinStreamBodySize, delete, maxWriteBufferSize, huffmanEncode, handshakeCount, close, HttpBodyCallback, encodeRstStream, BodyStream, onClientData, reserveFrameHeader, encodePriority, newHttpServer, H2Stream, Callback, feed, cancelObserver, pop, H2ClientMaxStreamsHint, AsyncHttpClient, hpackError, newHpackContext, bodyView, onError, send, HttpConnPool, H2DefaultMaxFrameSize, feed, emit, ListenerHandle, watchOsSignals, watchOsSignal, listen, signalNumber, newOsSignalRelay, listen, OsSignal, SIG_BLOCK, unlisten, newSignalRelay, listenOnce, listenOnce, close, FileSystemEvent, FileWatcherCb, newFileWatcher, FileWatcher, HeartbeatMs, HttpConnect, HttpPatch, ==, HttpGet, HttpHead, ThreadPoolError, HttpPost, HttpMethod, shutdownThreadPool, newThreadPool, FdCallback, getLoop, TimerCallback, closeThreadPool, EventType, HttpPut, HttpOptions, TlsState, TimerId, HttpDelete, HttpTrace, submitWork, ObserverCallback, Callback, iouEnabled, ThreadPool, DefaultMaxFrameSize, onMessage, releaseBuf, newWsConnection, ==, parseWsFrames, WsMessageCb, addIdle, newWsClient, WsCloseCb, setAlpnProtocols, writeFrameMasked, WsRetryCb, unregister, HttpGet, onMessage, run, writeFrame, HttpConnect, alpnSelected, connect, pollWallSec, HttpPatch, newWsServer, monoMs, addCleanup, WsErrorCb, isRunning, acquireBuf, listen, HttpHead, onOpen, newWsServer, cancelObserver, sendPong, sendMessage, timerCount, poll, WsServer, TlsState, close, HttpPost, HttpMethod, sendHandshakeRequest, SslError, sendText, HttpDelete, cancelTimer, reset, FdCallback, WsConnection, websocketUpgrade, onGiveUp, close, remove, WsError, session, register, postToLoop, connect, removeIdle, isTlsActive, wrapTls, newLoop, sendMessage, sendBinary, getProtocol, pollNowMs, closeWs, TimerId, newServerTlsContext, upgradeToWs, computeAcceptKey, connectWs, DefaultWsReconnectPolicy, sendMessage, deferCall, add, newClientTlsContext, observe, WsFrameKind, addTimer, onRetry, unregisterFd, close, EventType, HttpPut, TimerCallback, resumeTimer, PlatformEvent, HttpOptions, HttpTrace, isConnected, addTurnEndHook, ensureCapacity, parseWsUrl, sendPing, pauseTimer, Platform, addInterval, modify, handshakeCount, onClose, FdWatcher, init, WsClient, SslContext, run, runOnce, buildHandshakeResponse, WsGiveUpCb, attemptCount, modify, onOpen, WsOpenCb, sendMessage, sendHandshake, start, setTlsContext, poll, isEstablished, TlsRole, onClose, onError, ObserverCallback, close, Callback, Loop, wake, onError, iouEnabled, WsReconnectPolicy, Observer, stop