websockify: a WebSocket to TCP bridge for browser clients
Websockify is a WebSocket to TCP proxy/bridge. This allows a browser to connect to any application/server/service.
At a glance
- What is it?
- websockify turns a WebSocket connection into a plain TCP socket, which is what lets a browser talk to VNC, telnetd or any other service that only speaks raw TCP. It is a single-purpose proxy with a plugin system for tokens and authentication, and its rough edges are mostly around certificates and deployment.
- Who is it for?
- websockify fits teams that need a browser to reach an existing TCP service, especially alongside noVNC, because the proxy is small, the token plugin lets one process route many clients, and the wrap mode removes the need to change the target program. It is the wrong tool if you need a general HTTP reverse proxy, TLS termination for non-WebSocket traffic, or a proxy that does not require a trusted certificate for wss://.
- Can I use it commercially?
- Yes, with conditions. LGPL-3.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 128 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What websockify bridges, and who needs that bridge
Browsers can open WebSocket connections. VNC servers, telnetd, and most long-lived services cannot. websockify sits between them: it accepts the WebSocket handshake, parses it, and then forwards bytes in both directions between the client and the target socket. The README describes it as translating WebSockets traffic to normal socket traffic, and that is the whole job. The project was formerly named wsproxy and was part of noVNC, which explains the shape of its audience. If you are running noVNC in a browser and pointing it at a VNC server, you need something to convert the browser's WebSocket frames into the raw TCP stream that the VNC server expects. websockify is that something. It is also useful for any other service that predates WebSockets: a serial console, a telnet daemon, an SSH session wrapped by a client that speaks the WebSocket subprotocol. The tool does not add a protocol on top of the target. It does not understand VNC or telnet semantics. It moves bytes, and the client on the other end is responsible for the application protocol.
The data path: handshake, sniffing, and bidirectional forwarding
The mechanism is visible in the README and the repository layout. websockify listens on a port, accepts the WebSocket handshake, parses it, and then begins forwarding traffic between the client and the target in both directions. The target can be a host and port on another machine, or a local program started by websockify itself. TLS is not configured by a separate listener. websockify detects SSL by sniffing the first byte from the client and wrapping the socket if the data starts with '\x16' or '\x80'. That means a single port can serve both ws:// and wss:// depending on what the client sends first, which is convenient but also means the decision happens before any application data is read. The repository contains a rebind directory and a rebind.c source file, plus a Makefile whose only target is rebind.so. That shared library is the wrap mode: it intercepts bind() system calls by the wrapped program, moves the specified port to a free high port on loopback, and websockify then proxies WebSocket traffic directed at the original port to the moved port. This is why wrapping a program does not require editing the program's configuration. The trade-off is that the mechanism depends on LD_PRELOAD, so it is a Unix-oriented feature and the README does not describe a Windows equivalent.
Installing websockify and running a first proxy to a VNC server
setup.py declares the package name websockify, version 0.13.0, python_requires >=3.6, and a console script entry point named websockify that maps to websockify.websocketproxy:websockify_init. The declared install dependencies are numpy, requests, jwcrypto>=0.9.0 and redis, so a plain install pulls in more than the proxy core. The README gives no pip command, so the run script shipped at the top level of the repository is the entry point its examples use. The README's own wrap example uses that script and the --wrap-mode flag, with the target replaced by -- followed by the program command line:
./run 5901 --wrap-mode=ignore -- vncserver -geometry 1024x768 :1The --wrap-mode=ignore choice matters because vncserver backgrounds itself, and the README notes that the option indicates what action to take when the wrapped program exits or daemonizes. For a program that exits after each connection, the README shows --wrap-mode=respawn instead:
sudo ./run 2023 --wrap-mode=respawn -- telnetd -debug 2023If you need encryption, the README gives the openssl command for a self-signed certificate:
openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pemBy default websockify loads a certificate file named self.pem; the --cert=CERT and --key=KEY options override the file name.
Certificate handling is the part that bites first
The README is explicit that browsers generally do not give you the trust prompt when you open a WSS socket with an invalid certificate. A self-signed certificate therefore has to be accepted by the browser through another route: install it as an accepted certificate, or serve an HTTPS page with the same certificate and approve it there. The README also notes that ports are treated as separate origins by the browser, so if your site is on https://my.local:8443 and the WebSocket is on wss://my.local:8001, you have to browse to each port and add an exception separately before the page on :8443 can open a WSS connection to :8001. That is a real operational cost for anyone expecting a drop-in TLS proxy. With a commercial certificate, the README says to concatenate the server certificate first and then the intermediate certificates from the CA into one file, point --cert at that file, point --key at the key, and use --ssl-only as needed. The README does not document rollback or certificate rotation, so plan for a restart when the certificate file changes.
Tokens, authentication plugins, and the mini web server
A single websockify instance does not have to serve one target. The README describes token plugins: the client sends a token URL parameter, or reaches websockify by a hostname when --host-token is used, and websockify connects that client to one of several pre-configured targets. This is activated with --token-plugin CLASS and --token-source ARG, where CLASS is usually one from token_plugins.py. Authentication works the same way, with --auth-plugin CLASS and --auth-source ARG, and --web-auth extends the requirement to normal web requests. The --web DIR option turns on a mini web server on the same port as the proxy, serving files from DIR; that is how noVNC's HTML and JavaScript get delivered without a second process. Session recording with --record writes traffic sent and received from the client to a file, and -D daemonizes the process. Logging goes to a file with --log-file FILE. The plugin files are part of the websockify package and the README points at them by name, but it does not document the plugin interface in detail, so anyone writing a custom token or auth plugin will be reading the source.
When websockify is the wrong layer
websockify is a byte forwarder, and that is the limitation. It does not terminate HTTP, route by path, or rewrite headers, so it is not a replacement for nginx or Caddy in front of a web application. It does not understand the application protocol, so it cannot enforce VNC authentication or inspect telnet commands; authentication is limited to the plugin hooks described above. The wrap mode depends on rebind.so and LD_PRELOAD, which the README presents without a Windows equivalent, so wrapping a program on Windows is not covered. The README states that starting with version 0.5.0 only the HyBi / IETF 6455 WebSocket protocol is supported and there is no support for the older Base64 encoded data format, which rules it out for clients that still speak the older protocol. TLS detection by sniffing the first byte is clever, but it also means a client that sends something other than a TLS record or a WebSocket handshake on that port will not be handled as either.
Alternatives and how they differ
The README itself points to sister repositories: websockify-js for a JavaScript/Node.js implementation and websockify-other for C, Clojure and Ruby. Those are alternate implementations of the same proxy idea, so the difference is the runtime you already operate, not the architecture. The README also links an alternate implementation Feature Matrix on the wiki for external projects that implement the websockify protocol. A more substantive alternative is a general-purpose reverse proxy that supports WebSocket upgrade, such as nginx. The difference in approach is that nginx terminates TLS and HTTP and forwards an upgraded connection to a backend that already speaks WebSocket, whereas websockify converts a WebSocket connection into a raw TCP connection. If your backend already speaks WebSocket, you do not need websockify. If your backend speaks VNC or telnet over TCP, a reverse proxy alone will not help, because nothing on the path is translating the frame format. That is the specific gap websockify fills.
Maintenance, licence, and upgrade cost
The repository is not archived, and the last push was on 2026-05-24. Releases are infrequent: v0.13.0 on 2025-02-12, v0.12.0 on 2024-06-03, and v0.11.0 on 2022-12-16. The gap between v0.11.0 and v0.12.0 was about eighteen months, so an upgrade cadence measured in years is realistic. The declared dependencies (numpy, requests, jwcrypto>=0.9.0, redis) mean that installing websockify pulls in a numerical library and a Redis client even if you only use the basic proxy path, which increases the surface you have to track for updates. The package is licensed LGPLv3 per setup.py, and the repository carries a COPYING file. LGPL-3.0 has implications for how you distribute a modified websockify or a program that links against it, including the rebind.so wrap library. This is not legal advice; if you ship websockify inside a product, read COPYING and the licence identifier in setup.py and get your own review. The Python requirement is >=3.6, and the classifiers list 3.6 through 3.13, so the supported interpreter range is wide.
Editorial conclusion
websockify fits teams that need a browser to reach an existing TCP service, especially alongside noVNC, because the proxy is small, the token plugin lets one process route many clients, and the wrap mode removes the need to change the target program. It is the wrong tool if you need a general HTTP reverse proxy, TLS termination for non-WebSocket traffic, or a proxy that does not require a trusted certificate for wss://. Before adopting it, verify that the target port is reachable from the proxy host, decide whether you will use a self-signed certificate or a real one with the intermediate chain concatenated into the --cert file, and confirm that the LGPL-3.0 terms are acceptable for the way you ship it.
Frequently asked questions
What is websockify used for?
It translates WebSocket traffic to normal socket traffic so a browser can reach a service that only speaks raw TCP. The README describes it as accepting the WebSocket handshake, parsing it, and forwarding traffic between the client and the target in both directions.
How do I install websockify?
The package metadata in setup.py declares the name websockify and a console script entry point, so installing it provides the websockify command. The README does not give a pip command, but the repository also ships a run script that its examples invoke.
How do I use websockify?
Give it a listening port and a target host and port, and it forwards WebSocket bytes to that target. The README also documents wrapping a local program by replacing the target with -- followed by the program command line, and the --web DIR option to serve web files on the same port.
Is there a websockify alternative?
The README points to websockify-js for JavaScript/Node.js and websockify-other for C, Clojure and Ruby, plus a Feature Matrix on the wiki for external implementations. A general reverse proxy such as nginx differs because it forwards an already-upgraded WebSocket connection rather than converting WebSocket frames into a raw TCP stream.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/novnc-websockify)
Community notes