Skip to content

Repository files navigation

WebSpeak3 logo

WebSpeak3

License Docker Build Node Version Rust Version Latest Release Project Status

A modern, self-hosted browser client for TeamSpeak, TeaSpeak, and GreenTeaSpeak servers — no install, just open a tab.

🌐 Website · 💬 Open Client · 🕹️ Live Demo · 🚀 Quick Start · 📖 Installation · 🗺️ Roadmap · 🐛 Report Bug

The live demo runs entirely in your browser with simulated data — no real TeamSpeak server involved. It's there to show the UI, not the real connection.


📸 Preview

Desktop Mobile
WebSpeak3 desktop client connected to a TeamSpeak server WebSpeak3 mobile client connected to a TeamSpeak server

🚀 Quick Start

Run the ready-made container and open http://localhost:8080:

docker run -d --name webspeak3 --restart unless-stopped -p 8080:8080 moepchi/webspeak3:latest

Enter the address and port of any reachable TeamSpeak 3, TeamSpeak 6, TeaSpeak, or GreenTeaSpeak server in the connection dialog. The server does not need to be installed on the same machine, modified, or operated by you.

Voice requires a secure context. Microphone access works on localhost; for access from other devices, place WebSpeak3 behind an HTTPS reverse proxy.

✨ Features

🔌 Real TeamSpeak protocol Connects to actual TS3/TS6, TeaSpeak, and GreenTeaSpeak servers over a WebSocket gateway — the server stays exactly as-is
🎙️ Low-latency voice Opus-encoded voice with voice activation ("Sprachaktivierung") and adjustable sensitivity
🤫 Whisper Target your voice at specific channels or clients instead of your whole current channel
🔊 Custom audio output picker Route playback to any output device — works even in browsers without AudioContext.setSinkId
💬 Full text chat Channel, server-wide, and private (1:1) chat, each in its own tab — Shift+Enter for a newline
🌳 Live channel/client tree Correct ordering, status icons (channel commander, away, muted, deafened), country flags, click to switch channels
🖱️ Right-click context menu Private chat, poke, copy name, and whisper-target toggle straight from a client's row
📜 Server log Join/leave/switch, channel-group, and channel/server-change events shown inline, like the native client
🔔 Custom sound notifications Per-event sounds (connect, poke, messages, ...) with volume control and .ts3soundpack import
🪪 Persistent identity Keeps the same client UID across sessions instead of generating a new one every connect
👉 Poke & away status Poke clients with an optional message; set yourself away with presets or a custom status
Favorites & reconnect Remembers your last server/nickname; switch servers without leaving your tab
📱 Mobile-friendly layout Responsive single-column layout for narrow screens, not just a shrunk desktop UI
🌍 Localized UI Interface available in German, English, and Simplified Chinese, detected automatically or switchable in Options
🌗 Dark / light theme Clean, modern UI that adapts to your preference
🔁 Multi-join (server tabs) Several connections in parallel — one tab per server, like GreenTeaSpeak 2. Audio stays on the active tab
🔁 Seamless reconnect Switch or add connections mid-session without tearing down unrelated tabs
🍵 GreenTeaSpeak support Connects to real GreenTeaSpeak servers (not just TS3/TS6/TeaSpeak), plus an optional GTS-styled UI chrome (dark panels, gold menu bar, connection-tab strip) alongside the default look
🖥️ Screen streaming to/from TS6 ALPHA · UNSTABLE Share your screen to native TeamSpeak 6 clients and watch theirs. Built on TS6's undocumented Stream/Call protocol — expect it to break; see Roadmap

🧱 Tech Stack

React Vite TypeScript Node.js Rust Docker

🏗️ Architecture details

Browsers can't send raw UDP, which is what TeamSpeak's native protocol runs over, so a pure client-side implementation isn't possible — a server-side gateway is required that speaks the real TS protocol on one side and WebSocket to the browser on the other.

Browser (web/)  <--WebSocket-->  Gateway (gateway/)  <--stdin/stdout JSON-->  Rust connector (connector/)  <--TS3/TS6/TeaSpeak/GreenTeaSpeak protocol-->  Server
  • web/ — Vite + React frontend. TS3-lookalike UI: channel tree, chat tabs, voice controls. Optional GreenTeaSpeak-styled chrome for the connection-tab strip and menu bar.
  • gateway/ — Node.js/TypeScript WebSocket server. Spawns the Rust connector per browser WebSocket and relays newline-delimited JSON events between it and the browser. Multi-join opens one /ws connection per server tab (parallel connectors).
  • connector/ — Rust binary wrapping tsclientlib (vendored as a git submodule in tsclientlib/, currently tracking a fork with TeaSpeak/GreenTeaSpeak protocol support), the actual TS3/TS6/TeaSpeak protocol implementation. Handles connecting, channel/client state, chat, and Opus-encoded voice. Auto-detects the server dialect on connect (or it can be forced via --server-type).

🌐 Browser Support

Browser Status Notes
Chrome / Edge / Chromium ✅ Primary target Recommended for the most complete audio and device support
Firefox ✅ Supported Core client and voice functionality are supported
Safari 🧪 Experimental Audio and microphone behavior still needs broader real-device testing
Mobile Chromium ✅ Supported Responsive client with microphone support over HTTPS
Mobile Safari 🧪 Experimental UI is responsive; audio behavior remains under active validation

WebSpeak3 is a public beta. See the beta roadmap for the current scope, known limitations, and the next milestones.

🚀 Installation

🐳 Docker (recommended)

Clone the repo (the Rust connector depends on a git submodule, so pull it in too):

git clone --recurse-submodules https://github.com/Moepchi/webspeak3.git
cd webspeak3

This is what ships in docker-compose.yml:

services:
  webspeak3:
    build: .
    image: moepchi/webspeak3:latest
    container_name: webspeak3
    restart: unless-stopped
    environment:
      - PORT=8080

Port publishing is left out on purpose — set it in a local, gitignored docker-compose.override.yml so it doesn't clash with whatever else is already using a port on your host:

services:
  webspeak3:
    ports:
      - "8080:8080"

Then docker compose up -d and open http://localhost:8080 (or whatever host port you chose).

Prefer to skip the build entirely? A prebuilt image is published on Docker Hub:

docker run -d -p 8080:8080 --name webspeak3 moepchi/webspeak3:latest

The UI shows a small Ko-fi donation button in the bottom right corner. Building it yourself and would rather not carry someone else's donation link? docker compose build --build-arg DONATE_URL= removes it (any other value points it somewhere else). Outside Docker the same thing is a build-time variable: VITE_DONATE_URL= npm run build in web/.

The Design Store (browse/upload community themes) points at the maintainer's shared catalog by default, same as the official client — no setup needed. Want to run your own store instead, backed by your own gateway (STORE_ENABLED=1, see below)? docker compose build --build-arg STORE_URL=https://your-gateway.example.com/api/store/themes. Outside Docker: VITE_STORE_URL=https://your-gateway.example.com/api/store/themes npm run build in web/.

Environment variables

All optional; add them under environment: in your compose override next to PORT.

Variable Default Purpose
PORT 8080 Port the gateway listens on.
WEB_STATIC on Set to 0 to disable serving the built UI (web/dist) entirely — the gateway then only answers /ws, /api/feedback and /healthz. Use this when the UI is hosted elsewhere (e.g. a CDN/static host) and the gateway is purely a backend.
WEB_DIST web/dist next to the gateway Overrides the directory served when WEB_STATIC is on. Only needed for non-standard layouts.
BROADCAST_TOKEN unset Bearer token required to call /api/broadcast (send an in-app notice to all connected clients before a maintenance restart). Endpoint 404s while unset.
TLS_CERT / TLS_KEY unset Paths to serve the gateway over HTTPS/WSS directly instead of behind a reverse proxy/tunnel. Both must be set together.
STORE_ENABLED off Set to 1 to turn this gateway's own /api/store/themes endpoint on. Only needed if you want to run your own Design Store instead of using the maintainer's shared one (see STORE_URL build arg above) — the endpoint 404s while unset.
STORE_DATA_FILE store-themes.json in the container's working dir Where submitted themes (including screenshots) are stored. Mount a volume over this path if they should survive a container recreate.
STORE_ALLOWED_ORIGIN * CORS origin allowed to call the store endpoint, if you want to restrict it to your own frontend's origin.
STORE_ADMIN_TOKEN unset Bearer token that lets its holder publish under the reserved author name(s) and moderate (delete) any theme. Without it, nobody can.
🛠️ Manual installation (without Docker)

Prerequisites

  • Node.js 20+ and npm
  • Rust (stable toolchain) — rustup.rs
  • CMake and a C/C++ toolchain — needed to build the Opus codec library (audiopus_sys) used for voice. On Windows, the Visual Studio "Desktop development with C++" workload covers this; on Linux, install cmake and build-essential (or equivalent); on macOS, cmake via Homebrew plus Xcode command line tools.
  • git

1. Clone the repository

The Rust connector depends on the tsclientlib crate, vendored as a git submodule — make sure to pull it in too:

git clone --recurse-submodules https://github.com/Moepchi/webspeak3.git
cd webspeak3

If you already cloned without --recurse-submodules:

git submodule update --init --recursive

2. Build the Rust connector

cd connector
cargo build

Note: if the build fails with a CMake error like Compatibility with CMake < 3.5 has been removed, it's because the vendored Opus source uses an old cmake_minimum_required. Work around it with:

CMAKE_POLICY_VERSION_MINIMUM=3.5 cargo build

(On Windows PowerShell: $env:CMAKE_POLICY_VERSION_MINIMUM = "3.5"; cargo build)

This produces connector/target/debug/ts-connector (or ts-connector.exe on Windows), which the gateway spawns automatically — no manual step needed after this.

3. Install and start the gateway

cd gateway
npm install
npm run dev

This starts the WebSocket gateway on ws://localhost:8080. Open http://localhost:8080 for the UI (serves web/dist). After UI changes run cd web && npm run build, then reload. Optional Vite (npm run dev in web/, typically :5173) is only for HMR. WEB_STATIC=0 npm run dev serves API/WebSocket only.

4. Install and start the web frontend

In a separate terminal:

cd web
npm install
npm run dev

Vite will print a local dev URL (typically http://localhost:5173) — open it in a browser. The Vite app connects to the gateway at ws://localhost:8080/ws.

Preferred UI: http://localhost:8080 (static web/dist — refresh after cd web && npm run build). Vite :5173 is optional HMR only.

5. Connect

In the web UI, enter the address of a TeamSpeak server and a nickname, then click Connect. Voice requires microphone permission when you enable the mic button; the output-device picker (if your browser supports it) requires no extra permission.

Rebuilding after changes

  • Frontend and gateway changes hot-reload automatically (npm run dev in both cases).
  • Connector changes require a rebuild (cargo build in connector/) and a reconnect from the browser — if the old ts-connector binary is still running (an active browser connection), disconnect first or the build will fail to overwrite the binary.

🔗 Auto-Connect Links

Skip the connect dialog entirely and drop visitors straight into a TeamSpeak server. Two ways to do it — use either, or both together.

1. Share a link

Add a connect parameter to your instance's URL and send that link out — in a Discord post, a landing page button, a QR code, wherever:

https://your-instance/?connect=voice.example.com&nickname=Guest&channel=Lobby&token=abc123
Parameter Required What it does
connect yes Server address to join, host or host:port
nickname no Nickname to connect with — omit it and the visitor gets an auto-generated Guest-XXXX
channel no Default channel to join
token no Server/channel privilege key, if the target requires one

This works on any deployment — no rebuild, no configuration. WebSpeak3 connects as soon as the page loads and immediately strips these parameters from the address bar, so refreshing the tab (or someone screenshotting/forwarding the URL later) won't silently reconnect off a stale link.

2. Bake in a default server

Running a dedicated instance for one community or event? Set a default at build time so every visitor auto-connects with zero parameters, no link needed:

docker compose build --build-arg DEFAULT_SERVER=voice.example.com --build-arg DEFAULT_CHANNEL=Lobby

Outside Docker, the same thing is a build-time variable:

VITE_DEFAULT_SERVER=voice.example.com VITE_DEFAULT_CHANNEL=Lobby npm run build

(in web/). Leave DEFAULT_CHANNEL/VITE_DEFAULT_CHANNEL out to just join the server's default channel.

A share link (above) always takes priority over the baked-in default when both are present — so you can point most visitors at your default server while still sending specific people somewhere else via link.

Either way: on your own hosted instance, the mandatory first-visit Terms of Use is shown and accepted before anything auto-connects; and if the connection fails, the connect dialog opens prefilled so the visitor can fix it and retry by hand.

Credits

The vast majority of this project's code was written by Claude Code (Anthropic's Claude), working iteratively with the repo owner one feature at a time.


Legal / Disclaimer

WebSpeak3 is an independent, open-source, self-hosted project and is not affiliated with, associated with, authorized by, endorsed by, or in any way officially connected with TeamSpeak Systems GmbH.

"TeamSpeak", "TS3", and related logos or names are registered trademarks of TeamSpeak Systems GmbH. Likewise, WebSpeak3 is not affiliated with, associated with, authorized by, or endorsed by TeaSpeak or GreenTeaSpeak; "TeaSpeak" and "GreenTeaSpeak" are names of their respective projects/ operators. All product and company names are trademarks™ or registered® trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.

About

Open-source, self-hosted TeamSpeak 3/6 client for the browser — connect to any reachable server.

Topics

Resources

Stars

20 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages