A modern, self-hosted browser client for TeamSpeak 3 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.
| Desktop | Mobile |
|---|---|
![]() |
![]() |
Run the ready-made container and open http://localhost:8080:
docker run -d --name webspeak3 --restart unless-stopped -p 8080:8080 moepchi/webspeak3:latestEnter the address and port of any reachable TeamSpeak 3 or TeamSpeak 6 server in the connection dialog. The TeamSpeak 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.
| 🔌 Real TeamSpeak protocol | Connects to actual TS3/TS6 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 and English, detected automatically or switchable in Options |
| 🌗 Dark / light theme | Clean, modern UI that adapts to your preference |
| 🔁 Seamless reconnect | Switch connections mid-session — old state tears down cleanly, no leaks or duplicates |
🏗️ 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 protocol--> TeamSpeak Server
web/— Vite + React frontend. TS3-lookalike UI: channel tree, chat tabs, voice controls.gateway/— Node.js/TypeScript WebSocket server. Spawns the Rust connector per browser connection and relays newline-delimited JSON events between it and the browser.connector/— Rust binary wrappingtsclientlib(vendored as a git submodule intsclientlib/), the actual TS3/TS6 protocol implementation. Handles connecting, channel/client state, chat, and Opus-encoded voice.
| 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.
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 webspeak3This is what ships in docker-compose.yml:
services:
webspeak3:
build: .
image: moepchi/webspeak3:latest
container_name: webspeak3
restart: unless-stopped
environment:
- PORT=8080Port 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🛠️ 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, installcmakeandbuild-essential(or equivalent); on macOS,cmakevia 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 webspeak3If you already cloned without --recurse-submodules:
git submodule update --init --recursive2. Build the Rust connector
cd connector
cargo buildNote: 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 oldcmake_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 devThis starts the WebSocket gateway on ws://localhost:8080.
4. Install and start the web frontend
In a separate terminal:
cd web
npm install
npm run devVite will print a local dev URL (typically http://localhost:5173) — open it in a browser.
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 devin both cases). - Connector changes require a rebuild (
cargo buildinconnector/) and a reconnect from the browser — if the oldts-connectorbinary is still running (an active browser connection), disconnect first or the build will fail to overwrite the binary.
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.
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. 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.


