WebSpeak — Self-hosted TeamSpeak Web Client & Browser Gateway

GitHub:
https://github.com/EchoSixHIYA/WebSpeak-client-for-TeamSpeak

Live Demo:
https://webspeak.online

Hey everyone,

I’ve been working on a project called WebSpeak for the past few months, and I thought it was finally ready to share with the TeamSpeak community.

WebSpeak is a self-hosted browser client and voice gateway for TeamSpeak 3 and TeamSpeak 6.

The original idea was very simple:

I wanted an easier way for friends, newcomers, and temporary guests to join an existing TeamSpeak server.

For regular TeamSpeak users, the desktop client is still the natural choice.

But sometimes you just want to send someone a link and let them join a voice channel immediately — especially for new community members, temporary guests, game sessions, or events.

With WebSpeak, you deploy the gateway once and then share a web address.

Open the page → enter a nickname → join → talk.

No additional setup is required on the guest side.


What is WebSpeak?

WebSpeak connects browser users to an existing TeamSpeak server.

Each browser session gets its own TeamSpeak client connection, so the TeamSpeak server continues to handle channels, identities, groups, and permissions normally.

The goal is not to replace the traditional TeamSpeak experience.

Instead, WebSpeak provides an additional, lightweight way to access an existing TeamSpeak community from a modern browser.

The main design goal is:

Make it easy to invite someone into TeamSpeak.


Features

WebSpeak currently supports:

  • TeamSpeak 3 and TeamSpeak 6

  • Automatic TS3 / TS6 protocol detection

  • Full channel and member tree

  • Channel switching

  • Opus voice communication

  • Voice Activation

  • Microphone and output-device selection

  • Individual member volume controls

  • Channel messages

  • Server messages

  • Private messages

  • Poke

  • Multi-target Whisper

  • Persistent TeamSpeak identities in the browser

  • Mobile and desktop responsive UI

  • Light and dark themes

  • Chinese, English and German interfaces

There is also an optional built-in WebRTC transport for low-latency browser audio.

If WebRTC cannot be used, WebSpeak can automatically fall back to the compatible transport.


Browser-native features

Since WebSpeak runs in the browser, I’ve also been experimenting with features that make sense specifically in a web-based voice environment.

One example is Accompaniment Sharing.

On desktop browsers, a user can select a window or browser tab containing audio and share that audio directly into the current TeamSpeak voice channel.

This can be useful for music, game audio, background audio, or other shared listening scenarios.

No virtual audio cable is required.


Administration

WebSpeak includes its own web administration console.

After deployment, normal configuration can be completed directly from the browser.

The admin console currently includes:

  • Default TeamSpeak target

  • Fixed-server or open-gateway access mode

  • WebRTC configuration

  • Managed invitation links

  • Active sessions

  • Connection history

  • Logs

  • Diagnostics

  • Database backup

  • Relay configuration

Managed invitation links can expire, have limited uses, and be revoked.

This makes it possible to create temporary access links for friends, new members, or events without exposing the TeamSpeak server password in the URL.


Relay / regional connectivity

WebSpeak also includes an optional UDP relay.

This is mainly intended for deployments where the WebSpeak gateway and the target TeamSpeak server have poor connectivity between regions, or where a more suitable network path is available through another node.

The relay only forwards TeamSpeak traffic used by WebSpeak sessions.

It is not intended to be a general-purpose VPN or proxy.


Setup

Docker Compose is the recommended deployment method.

git clone --depth 1 https://github.com/EchoSixHIYA/WebSpeak-client-for-TeamSpeak.git
cd WebSpeak-client-for-TeamSpeak

docker compose pull
docker compose up -d

Then open:

http://your-server:3040/admin

Complete the initial setup in the browser, and WebSpeak is ready to use.

Prebuilt Windows x64 and Linux x64 packages are also available for users who prefer not to deploy with Docker.

For public deployments, HTTPS is strongly recommended and is required for reliable browser microphone and window-audio permissions.


Live Demo

The public instance is currently hosted in Hong Kong, so latency from Europe may not represent the performance of a locally deployed WebSpeak instance.


WebSpeak is open source under the AGPL-3.0 license.

The project started as a small way to make it easier for friends to join my TeamSpeak server.

It has grown quite a lot since then, but the basic idea is still the same:

Share a link, join the server, and start talking.

Feedback, bug reports, and feature ideas are very welcome.

I’d especially love to hear from other TeamSpeak server owners. If you try WebSpeak with your own community, let me know how it goes.

I’m from China, and my English isn’t very good, but I’ll do my best to communicate through translation tools if needed. Please feel free to reply even if my responses are a little slow or awkward.

3 Likes

[0.2.2] — 2026-09-17

  • Added optional browser-side microphone noise suppression.

  • Refined volume interaction: desktop microphone and master-volume controls open on hover, with noise suppression in the microphone menu.

  • Improved error messages and error-code display on top of PR #2.

  • Added Russian and Japanese UI support and per-language welcome text configuration.

[0.2.1] — 2026-09-13

  • Unified connection-error display on the welcome page: preserve error codes, safely truncate unknown codes, and show traceable server reasons.

  • Added default IPv6 TeamSpeak target support and documented the required host, runtime, and network conditions.

v0.2.3

  • Added member-management entry points: drag-and-drop remains available, while the context menu now provides a “Move to” submenu with a “My channel” shortcut.
  • Added permission-aware direct member moves: authorized users can move clients without redundant channel-password prompts, while the action is unavailable without the required TeamSpeak permission.
  • Added client-avatar display, microphone mute-state synchronization, and remembered-identity recovery, with improved pointer-drag compatibility.
  • Refreshed feature screenshots and documentation pages for all five supported languages.
  • Fixed clipped lower content in the high-resolution desktop admin settings page and tightened relay-card width constraints.

v0.2.4

Cross-platform P2P screen sharing

  • Browser users and native TeamSpeak 6 clients can discover, start, and watch each other’s screen shares.
  • Screen media prefers a direct WebRTC/ICE path between browsers or between a browser and a native client; WebSpeak carries authorization, share state, and SDP/ICE signaling only.

Other changes

  • Added live status, viewer count, player volume, fullscreen, exit controls, and live WebRTC statistics.
  • Added browser capture settings up to 1080p and 60 FPS, with a standalone settings modal that keeps member cards compact.
  • Added homepage visitor numbering and refined screen-share card/viewing interactions.

v0.2.5

Skin system

  • Added the .wskin system for custom themes created according to the skin development standard.
  • Day and Night are provided as base styles, with the customized ILLUSIA theme bundled as a custom-skin example. These three built-in skins cannot be removed or disabled.
  • Includes a skin development guide and the official skin-development Agent Skill to help users create and package custom themes.

Wow really cool, I like the visitor count in the corner ha. Nice stuff!

1 Like

Thx! Glad you like it :grinning_face_with_smiling_eyes:

Thanks for building this. We run it for our TS6 community and it works great, even on iPhone.

1 Like

v0.2.7 · 2026-10-13

A more open skin system

  • A more open skin editor and runtime now let authors customize the style and position of any component and add widgets.
  • After entering the voice panel, open a new administrator-console window in the same browser and sign in to activate the skin editor.
  • The KAAK skin is included as a development example.
  • Updated the skin development Agent Skill.

Enhancements

  • Server addresses can now be resolved through SRV records and TeamSpeak Nickname entries.
  • Free mode supports managing multiple server tabs; these controls are unavailable in fixed-server mode.
  • Added a screen-share bitrate option.
  • WebSpeak now saves entered channel passwords in the browser.
  • Locked channels now show a lock icon.
  • Chat history is now stored persistently.

Bug fixes

  • Fixed address parsing.
  • Fixed focus conflicts between volume controls and dragging member cards.
  • Fixed user status being incorrectly parsed as unknown.

WebSpeak v0.3.0 — November 3, 2026

Plugin applications

  • Introduced plugin API v2, supporting independent browser applications and optional Node.js backends with custom routes, state management, communication, and application logic.
  • Applications can be installed from the GitHub store or local .wplugin packages. Administrators can configure, review, and enable applications. Updated packages require renewed trust.
  • Added a floating plugin launcher and application library that work independently of the selected skin. Application windows support dragging, resizing, minimizing, maximizing, and restoring. Minimizing an application or returning to the library keeps it loaded.
  • Added an application template, development guide, and Agent Skill. P2P File Transfer and Watch Together are available through separate repositories.

Skins and authorization

  • Added a single first-visit authorization prompt covering the instance’s third-party skins and plugins. Connection credentials are excluded from the information provided to these extensions.
  • Added an Authorization option at the end of the skin menu so users can change their choice at any time.
  • Users who decline authorization can continue using the built-in Day, Night, and ILLUSIA skins. KAAK, other third-party skins, and plugin access are hidden.
  • Revoking authorization restores a built-in skin, cancels pending loads, and stops related components and application pages.
  • Package permissions, data filtering, package integrity checks, and host action validation remain enforced. Administrator review and trust decisions are handled separately.

Fixes and upgrades

  • Fixed native TeamSpeak clients failing to answer screen-sharing offers when sharing an application window, the entire screen, or content without audio. The required audio section is now negotiated without capturing the microphone or generating artificial audio.
  • Upgraded to @honeybbq/teamspeak@1.0.0-beta.23.
  • Improved handling of optional member fields and empty audio packets marking the end of speech.
  • Included upstream fixes for TSDNS resolution, Query flood-limit retries, file transfers, and disconnect cleanup.
  • Added security fixes for IPv6 target validation, concurrent administrator login attempts, session revocation after password changes, trusted-proxy rate limiting, and PCM audio uploads.
  • Preserved and verified the fix for third-party skins failing to load on the first visit.
  • Aligned application versions across desktop, web, and Android builds.

Upgrade notes

  • Plugin API v2 is incompatible with API v1 packages. Replacement applications must be updated, reviewed, and enabled.
  • Public plugin deployments require a separate HTTPS application origin, configured in administration and reverse-proxied to the application runtime port, which defaults to 3042. The application runtime and main website must use different origins.
  • Users will receive the new instance authorization prompt. Previous per-skin approvals are not automatically treated as consent.

WebSpeak v0.2.9 — October 24, 2026

Enhancements

  • Migrated to upstream SDK 1.0.0-beta.19. Regular voice connections now use the live client directory without requiring Query list permissions.
  • Added a GitHub skin store with instance-level installation, updates, and availability controls.
  • Released Discord Voice as an independently distributed, standard .wskin package.
  • Added optional TeamSpeak administration in fixed-server mode. Administrators can configure WebQuery, TCP Query, or SSH Query credentials to manage servers, channels, members, server groups, and bans.
  • Relay nodes can now advertise a direct browser voice endpoint and handle the complete voice session, avoiding an extra forwarding hop through the main gateway.
  • Added generic workspace persistence and reconnection APIs. KAAK now uses these APIs and includes shortcuts for administration, the WebSpeak GitHub project, and the project’s QQ group.
  • Added support for TeamSpeak channel spacers, including text alignment, repeated fills, blank rows, and standard line patterns. Spacer presentation data is also available to skins.

Fixes

  • Fixed screen-sharing fullscreen sizing.
  • Fixed cleanup of departed members’ state and playback resources.
  • Fixed successful bans incorrectly being reported as failures.
  • Excluded Query connections from member counts.
  • Fixed the channel-password label.
  • Improved error reporting to distinguish permission errors, rate limits, and timeouts.
  • A refresh failure following a successful administrative action now produces a separate warning, helping prevent duplicate actions.
  • Added protection against failed HTTP responses being interpreted as successful WebQuery results by the SDK.
  • Fixed Discord Voice homepage, chat, and narrow-screen control layouts.

Known issue in this release

  • The security hardening reported in PR #48 was not included in v0.2.9. These fixes were subsequently included in v0.3.0.

WebSpeak v0.2.8 — October 17, 2026

Screen sharing and connection reliability

  • Fixed negotiation and video-track handling for screen sharing between browsers and native TeamSpeak clients.
  • Improved handling of rapid channel switches to reduce inconsistent client state.
  • Fixed content rendering in some skin components and localization issues in KAAK.

Interface improvements

  • Audio device names are now displayed in full and wrap when space is limited, making devices with long names easier to identify.
  • Fixed avatar fallback text being selected unintentionally.

I set it up as a container, but I can’t log in to the admin panel — the page doesn’t load at all.

Hi! Other users have successfully deployed WebSpeak using Docker without any issues, so this is likely related to your local Docker or network configuration.

Please try the following steps:

  1. Check whether the container is running normally (docker ps).

  2. Check the container logs for errors (docker logs <container_name>).

  3. Make sure port 3040/TCP is accessible. If you’re using bridge networking, verify the port mapping.

  4. Try accessing http://YOUR_SERVER_IP:3040/admin directly, without a reverse proxy.

If the issue persists, please share your Docker configuration, container logs, and any browser error messages so we can investigate further.

  1. It is workin fine
  2. “docker logs 06535f08de01
    (node:1) ExperimentalWarning: SQLite is an experimental feature and might change at any time
    (Use node --trace-warnings ... to show where the warning was created)
    {“level”:40,“time”:“2026-11-04T15:27:30.610Z”,“pid”:1,“hostname”:“06535f08de01”,“msg”:“Default admin account created. Change the password on first login.”}
    {“level”:30,“time”:“2026-11-04T15:27:30.613Z”,“pid”:1,“hostname”:“06535f08de01”,“dataDir”:”/data",“msg”:“Starting WebSpeak server”}
    {“level”:30,“time”:“2026-11-04T15:27:30.633Z”,“pid”:1,“hostname”:“06535f08de01”,“component”:“web”,“component”:“voice-bridge”,“msg”:“Voice WebSocket endpoint ready at /ws/voice”}
    {“level”:30,“time”:“2026-11-04T15:27:30.635Z”,“pid”:1,“hostname”:“06535f08de01”,“component”:“web”,“port”:3040,“msg”:“Web server started”}"
  3. The port is available.
  4. What’s going on? It doesn’t work like this, it doesn’t even connect via IP address.
> Client: Docker Engine - Community
> Version:    29.4.0
> Context:    default
> Debug Mode: false
> Plugins:
> buildx: Docker Buildx (Docker Inc.)
> Version:  v0.33.0
> Path:     /usr/libexec/docker/cli-plugins/docker-buildx
> compose: Docker Compose (Docker Inc.)
> Version:  v5.1.2
> Path:     /usr/libexec/docker/cli-plugins/docker-compose
>
> Server:
> Containers: 15
> Running: 15
> Paused: 0
> Stopped: 0
> Images: 14
> Server Version: 29.4.0
> Storage Driver: overlayfs
> driver-type: io.containerd.snapshotter.v1
> Logging Driver: json-file
> Cgroup Driver: systemd
> Cgroup Version: 2
> Plugins:
> Volume: local
> Network: bridge host ipvlan macvlan null overlay
> Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
> CDI spec directories:
> /etc/cdi
> /var/run/cdi
> Swarm: inactive
> Runtimes: io.containerd.runc.v2 runc
> Default Runtime: runc
> Init Binary: docker-init
> containerd version: 301b2dac98f15c27117da5c8af12118a041a31d9
> runc version: v1.3.4-0-gd6d73eb8
> init version: de40ad0
> Security Options:
> apparmor
> seccomp
> Profile: builtin
> cgroupns
> Kernel Version: 5.15.0-202-generic
> Operating System: Ubuntu 22.04.5 LTS
> OSType: linux
> Architecture: x86_64
> CPUs: 4
> Total Memory: 7.673GiB
> Name: shystriknsk.ru
> ID: 13412d86-f79e-4d7e-bfcb-4da38f6236ac
> Docker Root Dir: /var/lib/docker
> Debug Mode: false
> Experimental: false
> Insecure Registries:
> ::1/128
> 127.0.0.0/8
> Live Restore Enabled: false
> Firewall Backend: iptables

Please note that you must use network_mode: host, not bridge?

Hi! Thanks for the additional information.

Your logs show that WebSpeak has started successfully and the web server is listening on port 3040.

I also noticed that your screenshot shows HTTP 503 (Service Unavailable), which suggests a possible reverse proxy or upstream connectivity issue.

Regarding Docker networking, the official Compose configuration uses network_mode: host, which is recommended. However, bridge networking should also work for the admin panel if port 3040:3040/TCP is correctly mapped.

Please try the following:

  1. Check the container’s network mode:docker inspect 06535f08de01 --format '{{.HostConfig.NetworkMode}}'

  2. Test the service directly on your Docker host(sorry i cant post this cmd, idk why):image

  3. If the local request works, check your firewall, port forwarding, and reverse proxy configuration.

Also, are you using Nginx, Cloudflare, or another reverse proxy for your domain?

Please share the results of the two commands above. This should help us identify where the connection is failing.

So, if it’s set to bridge, what happens if I change it to host. Nginx

We’ve found a likely cause!

Your latest screenshots show that:

  • HTTP on port 3040: Connection refused

  • HTTPS on port 3040: 200 OK

This means WebSpeak is running correctly, but its built-in HTTPS is enabled.

Your Nginx reverse proxy is probably trying to connect to WebSpeak using HTTP instead of HTTPS.

Please change your Nginx upstream from:

proxy_pass http://127.0.0.1:3040;

to:

proxy_pass https://127.0.0.1:3040;

If you’re using Nginx Proxy Manager, simply change the Scheme from http to https for the WebSpeak upstream.

If you’re using a self-signed backend certificate and have upstream certificate verification enabled, you’ll also need to configure Nginx to trust that certificate or disable verification for this local upstream.

You don’t need to switch from bridge to host networking. Your current Docker port mapping is clearly working over HTTPS.

Apply the Nginx changes and try accessing the admin panel again.