socks

Fully featured SOCKS proxy client for Node.js supporting SOCKS v4, v4a, and v5 with bind and UDP associate

Library
npm
v2.8.9
328stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
54/100Fair
Development Activity44
Maintenance20
Community72
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
68/100Good
Architecture74
Code Quality68
Innovation66
Learning Curve62

socks is a TypeScript-first SOCKS proxy client for Node.js that implements the full SOCKS v4, v4a, and v5 protocol suite, including the CONNECT, BIND, and ASSOCIATE commands. It hands back a raw net.Socket wired through the negotiated proxy tunnel, so any code that already speaks to a plain TCP socket works unmodified once the SOCKS handshake completes.

Beyond simple outbound connections, it supports proxy chaining (routing a connection through multiple SOCKS proxies in sequence), username/password and fully custom authentication handlers, and built-in UDP frame encoding/decoding for SOCKS5 ASSOCIATE relays. The library exposes callback, Promise, and EventEmitter interfaces for the same underlying connection flow, letting consumers pick whichever async style fits their codebase.

What You Get

  • A SocksClient class with static createConnection (Promise/callback) and createConnectionChain factory methods for the CONNECT command
  • Support for the BIND command (proxy listens and relays an inbound connection back to the client) and ASSOCIATE command (UDP relay) via event-driven connect() flow
  • Proxy chaining across multiple SOCKS servers with optional chain-order randomization
  • Username/password auth (SOCKS5) and a fully pluggable custom authentication method (request/response handlers) for non-standard auth schemes
  • Built-in SocksClient.createUDPFrame / parseUDPFrame helpers for building and reading SOCKS5 UDP relay packets
  • Full TypeScript type definitions shipped with the package, plus support for IPv4, IPv6, and hostname destinations

Common Use Cases

  • Routing outbound Node.js network requests (e.g. through Tor or a corporate SOCKS proxy) without modifying the calling code, by handing the resulting socket to an HTTP client or raw stream consumer
  • Building proxy-aware scrapers, crawlers, or automation tools that need to rotate through a pool of SOCKS proxies, including multi-hop chains for extra anonymity
  • Implementing SOCKS BIND-based reverse-connection patterns (e.g. FTP-style active connections) where a remote peer connects back through the proxy
  • Relaying UDP traffic (DNS lookups, game traffic, VoIP) through a SOCKS5 ASSOCIATE tunnel using the built-in UDP frame codec

Under The Hood

Architecture: The library centers on a single SocksClient class (src/client/socksclient.ts, ~1000 lines) that extends EventEmitter and drives a byte-level state machine (SocksClientState, in src/common/constants.ts) through the SOCKS handshake — ConnectingSentInitialHandshakeReceivedInitialHandshakeResponse → (auth states) → SentFinalHandshakeEstablished. Incoming socket data is buffered in a custom ReceiveBuffer (src/common/receivebuffer.ts) that accumulates bytes until nextRequiredPacketBufferSize is met, then the client parses the next protocol frame and advances state. Static factories (createConnection, createConnectionChain) wrap the instance-based connect()/event flow in Promise or callback sugar for the common CONNECT case, while BIND and ASSOCIATE are exposed only through the raw new SocksClient(options) + bound/established/error event API since they involve multiple async phases.

Tech Stack: Pure TypeScript (99.7% of the codebase) compiled to CommonJS (build/) with .d.ts typings (typings/) via tsc. Two runtime dependencies: smart-buffer for structured binary buffer reads/writes during handshake parsing, and ip-address for IPv4/IPv6 address validation and conversion (notably Address6 for IPv6 destination handling). No dependency on Node’s net beyond the standard library — sockets, chaining, and the Duplex stream abstraction (for existing_socket chaining) all come from Node core.

Code Quality: Tests live in test/ (two files, ~676 lines) using Mocha + assert, covering ReceiveBuffer behavior and SocksClient handshake/option-validation logic (socksclient.test.ts), run via ts-node/register against the TypeScript source directly (no separate test build step). Input validation is centralized in src/common/helpers.ts (validateSocksClientOptions, validateSocksClientChainOptions), which throws a typed SocksClientError (src/common/util.ts) carrying a stable error-message enum (ERRORS in constants.ts) rather than ad hoc strings, giving consumers something reliable to match on. ESLint + Prettier are configured and enforced via lint/prettier scripts, and the build script runs Prettier before tsc so formatting drift can’t reach the published output.

API Design: The public surface is intentionally small — one class, a handful of static factories, and a typed options object — while still supporting three async styles (callback, Promise, EventEmitter) on the same underlying flow, which keeps adoption friction low for both legacy callback-based code and modern async/await usage. Options objects (SocksClientOptions, SocksClientChainOptions, SocksProxy) are fully typed and documented inline with JSDoc comments, and the README’s quick-start example gets a working proxied net.Socket in under 15 lines. The one adoption cost is that BIND/ASSOCIATE require dropping to the lower-level event-driven API since they don’t map to a single request/response Promise.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search