websockify
WebSocket-to-TCP bridge for browser remote access
websockify is a WebSocket-to-TCP proxy that allows browser-based clients like noVNC to reach VNC and other TCP services. It is a small but essential component for self-hosted web remote access.
Key features
- WebSocket to TCP bridge
- Enables browser VNC
- Tiny footprint
- Multiple language ports
Pros & cons
Strengths
- Simple and reliable
- Widely depended upon
Trade-offs
- Single-purpose tool
- No UI of its own
websockify replaces
Last reviewed Sep 13, 2026 · 790 words
Every "VNC in a browser tab" you have used, from noVNC to the console button in Proxmox, OpenStack and oVirt, has something underneath doing one job: accepting a WebSocket connection from the browser and piping the bytes to a plain TCP socket, usually a VNC server on port 5900. Browsers cannot open raw TCP sockets, so something has to. websockify is the original implementation of that something and is still the one noVNC ships with. It is 32 MB of Python, it has no UI, and you will never look at it after the day you set it up, which is the highest compliment a piece of infrastructure gets.
Where it sits in a remote-access stack
The shape is browser, then TLS-terminating reverse proxy, then websockify, then the VNC (or serial-console, or other TCP) service. noVNC is static HTML and JavaScript that the browser loads and then connects from; websockify can serve those files itself with --web, or your reverse proxy can. Nothing in this chain authenticates the user unless you add it: VNC's own password is weak and optional, and websockify will forward anyone who reaches it. So the rule is the same as for every LAN-only tool. Bind it to localhost or a VPN address, put it behind a proxy that does auth and TLS, and never expose port 6080 to the internet directly.
The two-minute install
pip install websockify # or: apt install websockify
websockify --web=/usr/share/novnc 6080 localhost:5900
Open http://localhost:6080/vnc.html and you are looking at the desktop of whatever VNC server is on 5900. The noVNC repository bundles utils/novnc_proxy, which is a wrapper that runs exactly this. For something permanent, a systemd unit:
[Unit]
Description=websockify for noVNC
After=network.target
[Service]
ExecStart=/usr/bin/websockify --web=/usr/share/novnc 127.0.0.1:6080 127.0.0.1:5900
Restart=on-failure
User=novnc
[Install]
WantedBy=multi-user.target
A Caddy site block that reverse-proxies to 127.0.0.1:6080 handles the WebSocket upgrade with no extra configuration; nginx needs the Upgrade and Connection headers set explicitly or the connection dies the moment noVNC connects. The reverse proxy comparison covers which to use, and for this job either is fine.
One websockify, many targets
Running a separate websockify per machine gets old at three machines. The token plugin fixes that: one websockify, a file mapping tokens to targets, and the client passes ?token= in the URL.
websockify --token-plugin TokenFile --token-source /etc/websockify/targets 6080
with a targets file like:
office-pc: 192.168.1.20:5900
nas-console: 192.168.1.5:5901
That is the whole mechanism behind the console button in most web panels: a token per session, mapped to the right VM's VNC socket, forwarded through one listener. If you are building a small admin panel of your own it is a reasonable thing to reuse rather than reinvent. There is also --auth-plugin for basic authentication, --ssl-only with --cert and --key for TLS at websockify itself when there is no proxy in front, and a --heartbeat interval for keeping sessions alive through proxies that drop idle sockets.
The Python implementation is the reference; the README lists ports in Node, C and other languages, and several platforms embed their own. First released in 2010 and sitting at about 4,400 stars, it is depended on by far more software than its own star count suggests.
When you have outgrown it
websockify plus noVNC gives you a VNC session in a tab. It does not give you user accounts, an RDP or SSH client, session recording, or clipboard and file transfer done well. Apache Guacamole does all of that, with its own protocol daemon in place of websockify and a proper login in front; it is the far more complete project and the right pick for anyone giving a browser console to more than themselves. RustDesk is the answer if what you want is a remote desktop client rather than a browser at all. The three-way remote access article sets those against a plain VPN.
What I'd do
Keep websockify for what it is: the plumbing under a noVNC page for a homelab where you are the only user, run as a systemd service bound to localhost, fronted by Caddy with basic auth or reachable only over Tailscale. Use the token file the day you have a second target. The day you want to hand a browser console to another person, install Guacamole and let websockify retire quietly, which is what it was built to do.
Similar remote access & vpn apps
RustDesk
Remote Access & VPNOpen-source remote desktop alternative to TeamViewer
Replaces TeamViewer, AnyDesk
frp
Remote Access & VPNFast reverse proxy to expose local servers behind NAT
Replaces ngrok
Headscale
Remote Access & VPNOpen-source self-hosted Tailscale control server
Replaces Tailscale
Sunshine
Remote Access & VPNSelf-hosted game-stream host for Moonlight clients
Replaces NVIDIA GameStream, Parsec
Tailscale
Remote Access & VPNZero-config mesh VPN built on WireGuard
Replaces ZeroTier
JumpServer
Remote Access & VPNOpen-source bastion host and PAM platform
Replaces CyberArk, Teleport