tor-js-gateway

Tor in the browser

Gateway server for tor-js — enabling real Tor circuits built locally in your browser using WebAssembly. All cryptography runs on your machine. The gateway never sees your traffic or knows your destination — it just relays encrypted bytes.

Connect to a Tor relay

Open a socket to any consensus relay. The gateway automatically picks the best transport (WebRTC, WebSocket, or direct TCP):

import { Gateway } from 'https://this-server/torJsGateway.js'; const gw = new Gateway('https://this-server'); // Open a relay socket (auto-selects best transport) const sock = await gw.connect('198.51.100.1:9001'); sock.send(new Uint8Array([0x00, 0x07, ...])); sock.onmessage = (data) => { /* Uint8Array from relay */ }; sock.onclose = () => { /* closed */ }; // Open more sockets (WebRTC reuses its peer connection) const sock2 = await gw.connect('203.0.113.5:443'); // Or force a specific transport const wsGw = new Gateway('https://this-server', { strategies: ['websocket'], }); gw.close(); // close everything when done

Only addresses advertised in the current Tor consensus are allowed. The gateway rejects connections to non-relay or private IPs.

Bootstrap from this gateway

Download and parse the Tor consensus directly in the browser:

import { bootstrap } from 'https://this-server/torJsGateway.js'; const { consensus, microdescs, authcerts } = await bootstrap( 'https://this-server/bootstrap.zip.br', (ev) => console.log(ev.type), // optional progress callback ); console.log(`Got ${microdescs.length} relay descriptors`);
Run your own gateway
Install from source (requires Rust 1.89+):
cargo install --path . tor-js-gateway init # create config at ~/.config/tor-js-gateway/config.json5 tor-js-gateway # run in foreground tor-js-gateway install # or install as a systemd service
Manage the service with standard systemd commands:
systemctl --user status tor-js-gateway systemctl --user restart tor-js-gateway journalctl --user -u tor-js-gateway -f