JavaScript mumble client Fork of
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Martin Bober 8401e2cb02 Join channel provided in URL after connect (the ugly way) 4 years ago
app Join channel provided in URL after connect (the ugly way) 4 years ago
themes Add setting for showing user count after channel name 4 years ago
.gitignore Initial commit 6 years ago
Dockerfile change the dockerimage to run the process as node user 4 years ago Add way to set default values short of forking the whole project 4 years ago
package.json Fix users being shown in incorrect channel (fixes #38) 4 years ago
webpack.config.js Add way to set default values short of forking the whole project 4 years ago


mumble-web is an HTML5 Mumble client for use in modern browsers.

A live demo is running here.

The Mumble protocol uses TCP for control and UDP for voice. Running in a browser, both are unavailable to this client. Instead Websockets are used for all communications.

libopus, libcelt (0.7.1) and libsamplerate, compiled to JS via emscripten, are used for audio decoding. Therefore, at the moment only the Opus and CELT Alpha codecs are supported.

Quite a few features, most noticeably all administrative functionallity, are still missing.



mumble-web can either be installed directly from npm with npm install -g mumble-web or from git:

git clone
cd mumble-web
npm install
npm run build

The npm version is prebuilt and ready to use whereas the git version allows you to e.g. customize the theme before building it.

Either way you will end up with a dist folder that contains the static page.


At the time of writing this there do not seem to be any Mumble servers which natively support Websockets. To use this client with any standard mumble server, websockify must be set up (preferably on the same machine that the Mumble server is running on).

You can install websockify via your package manager apt install websockify or manually from the websockify GitHub page. Note that while some versions might function better than others, the python version generally seems to be the best.

There are two basic ways you can use websockify with mumble-web:

  • Standalone, use websockify for both, websockets and serving static files
  • Proxied, let your favorite web server serve static files and proxy websocket connections to websockify

This is the simplest but at the same time least flexible configuration.

websockify --cert=mycert.crt --key=mykey.key --ssl-only --ssl-target --web=path/to/dist 443 mumbleserver:64738

This configuration allows you to run websockify on a machine that already has another webserver running.

websockify --ssl-target 64737 mumbleserver:64738

A sample configuration for nginx that allows access to mumble-web at and connecting at wss:// (similar to the demo server) looks like this:

server {
        listen 443 ssl;
        ssl_certificate /etc/letsencrypt/live/;
        ssl_certificate_key /etc/letsencrypt/live/;

        location / {
                root /path/to/dist;
        location /demo {
                proxy_pass http://websockify:64737;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection $connection_upgrade;

map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;


The app/config.js file contains default values and descriptions for all configuration options. You can overwrite those by editing the config.local.js file within your dist folder. Make sure to back up and restore the file whenever you update to a new version.


The default theme of mumble-web tries to mimic the excellent MetroMumbleLight theme. mumble-web also includes a dark version, named MetroMumbleDark, which is heavily inspired by MetroMumble's dark version.

To select a theme other than the default one, append a theme=dark query parameter (where dark is the name of the theme) when accessing the mumble-web page. E.g. thisis the live demo linked above but using the dark theme (dark is an alias for MetroMumbleDark).

Custom themes can be created by deriving them from the MetroMumbleLight/Dark themes just like the MetroMumbleDark theme is derived from the MetroMumbleLight theme.

Matrix Widget

mumble-web has specific support for running as a widget in a Matrix room.

While just using the URL to a mumble-web instance in a Custom Widget should work for most cases, making full use of all supported features will require some additional trickery. Also note that audio may not be functioning properly on newer Chrome versions without these extra steps.

This assumes you are using the Riot Web or Desktop client. Other clients will probably require different steps.

  1. Type /devtools into the message box of the room and press Enter
  2. Click on Send Custom Event
  3. Click on Event in the bottom right corner (it should change to State Event)
  4. Enter im.vector.modular.widgets for Event Type
  5. Enter mumble for State Key (this value may be arbitrary but must be unique per room)
  6. For Event Content enter (make sure to replace the example values):
  "waitForIframeLoad": true,
  "name": "Mumble",
  "creatorUserId": "@your_user_id:your_home_server.example",
  "url": "$matrix_display_name&theme=$theme&avatarurl=$matrix_avatar_url",
  "data": {},
  "type": "jitsi",
  "id": "mumble"

The $var parts of the url are intentional and will be replaced by Riot whenever a widget is loaded (i.e. they will be different for every user). The username query parameter sets the default username to the user's Matrix display name, the theme parameter automatically uses the dark theme if it's used in Riot, and the avatarurl will automatically download the user's avatar on Matrix and upload it as the avatar in Mumble. Finally, the matrix=true query parameter replaces the whole Connect to Server dialog with a single Join Conference button, so make sure to remove it if you do not supply default values for all connection parameters as above. The type needs to be jitsi to allow the widget to use audio and to stay open when switching to a different room (this will hopefully change once Riot is able to ask for permission from the user by itself). The id should be the same as the State Key from step 5. See here for more information on the values of these fields. 7. Press Send