XMPP Web

March 4, 2026 ยท View on GitHub

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 in message and reactions (XEP-0444),
  • 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 (800 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

Installation

There are 4 different ways to install XMPP Web:

Ansible

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.

Archive

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

wget https://github.com/nioc/xmpp-web/releases/latest/download/xmpp-web-0.9.7.tar.gz \
  -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=https://domain-xmpp.ltd:5281/xmpp-websocket \
    -e APP_DEFAULT_DOMAIN=domain-xmpp.ltd \
    --name xmpp-web-1 nioc/xmpp-web
    
  • in a docker-compose.yml file:

    version: "3.4"
    services:
      xmpp-web:
        image: nioc/xmpp-web:latest
        ports:
          - "80:80"
        environment:
          - XMPP_WS=https://domain-xmpp.ltd:5281/xmpp-websocket
          - APP_DEFAULT_DOMAIN=domain-xmpp.ltd
    

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 https://github.com/nioc/xmpp-web.git xmpp-web
cd xmpp-web
pnpm install --frozen-lockfile
pnpm run build
nano dist/local.js
mv dist /var/www/xmpp-web
chown www-data /var/www/xmpp-web/ -R

Upgrade

Archive

Use the same method as installation or use the update.sh 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.

Configuration

local.js attributeEnvironment (Docker)Default (initial value)Description
nameAPP_NAME"XMPP web"Application name
transports.websocketAPP_WS"wss://chat.domain-web.ltd/xmpp-websocket"Websocket endpoint used by application (proxy or direct XMPP server)
hasRegisteredAccessAPP_REGISTERED_ACCESStrueSet to false to disable registered users components (guest access only)
hasGuestAccessAPP_GUEST_ACCESStrueSet to false to disable guest users components
anonymousHostXMPP_ANON_HOSTnullVirtual host used for guest access (anonymous)
isTransportsUserAllowedAPP_IS_TRANSPORTS_USER_ALLOWEDfalseAllow user to set endpoints on the fly in login component
hasHttpAutoDiscoveryAPP_HTTP_AUTODISCOVERYfalseAllow to retrieve a .well-known/host-meta.json if user log on a different domain
resourceAPP_RESOURCE"Web XMPP"Resource (client) affected to user
defaultDomainAPP_DEFAULT_DOMAIN"domain-xmpp.ltd"Domain used if user do not provide a full jid
defaultMucAPP_DEFAULT_MUCnullAutocomplete MUC address (ex: conference.domain.ltd) if user do not provide a full room jid (join & create)
isStylingDisabledAPP_IS_STYLING_DISABLEDfalseSet to true for disable messages styling
hasSendingEnterKeyAPP_HAS_SENDING_ENTER_KEYfalseIf true, Enter key sends message, it adds new line otherwise (Control+Enter always sends message)
connectTimeoutXMPP_CONNECT_TIMEOUT5000Timeout in ms before XMPP connection is considered as rejected
pinnedMucsAPP_PINNED_MUCS[]Jid MUC list to hightlight in guest rooms page, ex: ['welcome@conference.domain.ltd', 'vip@conference.domain.ltd']
logoUrlAPP_LOGO_URL''Custom logo URL for login/guest pages
guestDescriptionAPP_GUEST_DESCRIPTION''Welcome text for guests (allows some HTML tags like <p>, <a>, <b>, see allowed tags list)
sso.endpointAPP_SSO_ENDPOINTfalsePublic endpoint for SSO (must be secured: do not expose it without an authentication mechanism)
sso.jidHeaderAPP_SSO_JID_HEADER"jid"Header containing JID after SSO request
sso.passwordHeaderAPP_SSO_PASSWORD_HEADER"password"Header containing password after SSO request
N/AXMPP_WS''Websocket endpoint proxyfied by Nginx (on a docker installation)

Contributing

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.

You can also help by taking surveys and answering user questions in discussions.

Credits

  • Nioc - Initial work

See also the list of contributors to this project.

This project is powered by the following components:

License

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