Skip to content


Repository files navigation


license: AGPLv3 GitHub release GitHub downloads GitHub Docker workflow status GitHub E2E tests workflow status Docker Pulls Docker Image Size (latest by date) GitHub issues by-label

Lightweight web chat client for XMPP server.

Table of contents

Key features

  • Connect to an XMPP server with WebSocket,
  • Chat and groupchat (MUC as defined in XEP-0045),
  • Retrieve contacts (roster) and bookmarked rooms (XEP-0048),
  • Send and receive files over HTTP (XEP-0066, XEP-0363),
  • Handle password protected room,
  • Display and send chat state notifications: is composing, is paused (XEP-0085),
  • Format messages: bold, italic, striked, link and code inline/block (XEP-0393),
  • Pick emoji,
  • Room creation and configuration,
  • Apply message moderation (XEP-0425),
  • Display and edit vCard information (in particular the user avatar, XEP-0054),
  • PWA (Progressive Web App) creating user experiences similar to native applications on desktop and mobile devices,
  • Lightweight (600 KB gzipped at the first loading and then less than 10 KB)
  • Guest access /guest?join={jid} (joining a MUC anonymously as described in RFC 4505)

Screenshot desktop Screenshot mobile home Screenshot mobile chat Screenshot guest join


There are 4 different ways to install XMPP Web:


Long time ago, we provided an Ansible role. It had not been updated since 2020 and nobody used it, it is not maintained anymore. You can still use it but it will not set all the relevant configuration in local.js.


You can download latest .tar.gz archive, unpack files in web directory and configure:

wget \
  -O /var/tmp/xmpp-web.tar.gz \
  && cd /var/www \
  && tar -xvzf /var/tmp/xmpp-web.tar.gz \
  && chown www-data /var/www/xmpp-web/ -R

Docker image

On each release, we also build a Docker image which is the latest stable Nginx (Alpine variant in order to keep lightweight) serving the generated assets. Configuration in local.js is set up according to environment variables (names and meanings are explained in configuration section).

This can be used:

  • as standalone service:

    docker run -it -p 80:80 --rm \
    -e XMPP_WS= \
    -e \
    --name xmpp-web-1 nioc/xmpp-web
  • in a docker-compose.yml file:

    version: "3.4"
        image: nioc/xmpp-web:latest
          - "80:80"
          - XMPP_WS=

Build from source

If you want the latest code without waiting for the next release, you can clone this repo, build assets and copy dist files in web directory:

git clone xmpp-web
cd xmpp-web
npm ci
npm run build
nano dist/local.js
mv dist /var/www/xmpp-web
chown www-data /var/www/xmpp-web/ -R



Use the same method as installation or use the script. After that, do not forget to edit local.js.

Docker image

Use docker pull nioc/xmpp-web:latest and check if there is some new environment variables to set.


local.js attribute Environment (Docker) Default (initial value) Description
name APP_NAME "XMPP web" Application name
transports.websocket APP_WS "wss://" Websocket endpoint used by application (proxy or direct XMPP server)
hasRegisteredAccess APP_REGISTERED_ACCESS true Set to false to disable registered users components (guest access only)
hasGuestAccess APP_GUEST_ACCESS true Set to false to disable guest users components
anonymousHost XMPP_ANON_HOST null Virtual host used for guest access (anonymous)
isTransportsUserAllowed APP_IS_TRANSPORTS_USER_ALLOWED false Allow user to set endpoints on the fly in login component
hasHttpAutoDiscovery APP_HTTP_AUTODISCOVERY false Allow to retrieve a .well-known/host-meta.json if user log on a different domain
resource APP_RESOURCE "Web XMPP" Resource (client) affected to user
defaultDomain APP_DEFAULT_DOMAIN "" Domain used if user do not provide a full jid
defaultMuc APP_DEFAULT_MUC null Autocomplete MUC address (ex: if user do not provide a full room jid (join & create)
isStylingDisabled APP_IS_STYLING_DISABLED false Set to true for disable messages styling
hasSendingEnterKey APP_HAS_SENDING_ENTER_KEY false If true, Enter key sends message, it adds new line otherwise (Control+Enter always sends message)
connectTimeout XMPP_CONNECT_TIMEOUT 5000 Timeout in ms before XMPP connection is considered as rejected
pinnedMucs APP_PINNED_MUCS [] Jid MUC list to hightlight in guest rooms page, ex: ['', '']
logoUrl APP_LOGO_URL '' Custom logo URL for login/guest pages
guestDescription APP_GUEST_DESCRIPTION '' Welcome text for guests (allows some HTML tags like <p>, <a>, <b>, see allowed tags list)
N/A XMPP_WS '' Websocket endpoint proxyfied by Nginx (on a docker installation)


If you have a suggestion for a feature you think would enhance this product, please submit a feature request. Pull requests are welcomed (please create feature request for discussing it before), see contributing.


  • Nioc - Initial work

See also the list of contributors to this project.

This project is powered by the following components:


This project is licensed under the GNU Affero General Public License v3.0 - see the LICENSE file for details