Introduction
websocketd is a lightweight command-line tool that takes any program or script that uses STDIN/STDOUT and wraps it into a WebSocket server. Each incoming WebSocket connection spawns a new instance of the program. Messages from the client go to the program's STDIN and each line written to STDOUT is sent back as a WebSocket message. This lets you build real-time server applications in any programming language without a WebSocket library.
What websocketd Does
- Spawns a new process for each WebSocket connection, mapping STDIN/STDOUT to messages
- Works with programs written in any language: Bash, Python, Ruby, Go, Perl, or compiled binaries
- Serves static HTML/JS files alongside the WebSocket endpoint for self-contained demos
- Supports origin checking, TLS termination, and configurable connection limits
- Provides CGI-style environment variables with connection metadata to the child process
Architecture Overview
websocketd is a single Go binary. When a WebSocket client connects, websocketd forks the specified program and bridges the WebSocket frames to the process's standard streams. Each line on STDOUT becomes a text frame sent to the client. Each incoming text frame is written as a line to STDIN. When the process exits or the client disconnects, the other side is cleaned up. This inetd-like model keeps the architecture simple and language-agnostic.
Self-Hosting & Configuration
- Download a single binary from GitHub releases or install via Homebrew
- Run with
websocketd --port=PORT ./your-programto start serving - Use
--staticdir=./htmlto serve a web frontend alongside the WebSocket endpoint - Enable TLS with
--ssl --sslcert=cert.pem --sslkey=key.pem - Set
--maxforksto limit concurrent connections and prevent resource exhaustion
Key Features
- Zero-dependency single binary deployment on Linux, macOS, and Windows
- Language-agnostic design lets you prototype with shell scripts and scale to compiled programs
- STDERR from child processes is logged to the server console for debugging
- Built-in static file server eliminates the need for a separate HTTP server
- Environment variables expose client IP, request path, and headers to the child process
Comparison with Similar Tools
- Socket.IO — Requires a Node.js server and client library; websocketd works with any language
- ws (Node.js) — Library-level WebSocket support; websocketd wraps existing programs without code changes
- Caddy websocket — Plugin-based approach; websocketd is a standalone tool with simpler configuration
- socat — General-purpose relay; websocketd specifically handles WebSocket protocol framing
- gotty — Shares a terminal over the web; websocketd is bidirectional and program-agnostic
FAQ
Q: Does each client get its own process? A: Yes. Each WebSocket connection spawns a fresh instance of the program. State is per-connection by default.
Q: Can I use websocketd in production? A: websocketd is suitable for moderate workloads. For high-connection counts, consider placing it behind a reverse proxy with connection limits.
Q: What happens if the program crashes? A: The WebSocket connection is closed. The client can reconnect, which spawns a new process.
Q: Can I send binary data? A: websocketd operates on text lines by default. Binary data can be base64-encoded or handled through a wrapper script.