XMPP Web
March 4, 2026 ยท View on GitHub
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)

Installation
There are 4 different ways to install XMPP Web:
- using Docker image (easiest, strongly recommended),
- using release archive,
- build from source code (latest code but hardest).
from provided Ansible role(not maintained),
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:
- download latest release,
- unarchive,
- set files owner (example:
www-datawith Apache), - create Apache virtual host,
- configure
local.js.
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.ymlfile: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 attribute | Environment (Docker) | Default (initial value) | Description |
|---|---|---|---|
name | APP_NAME | "XMPP web" | Application name |
transports.websocket | APP_WS | "wss://chat.domain-web.ltd/xmpp-websocket" | 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-xmpp.ltd" | Domain used if user do not provide a full jid |
defaultMuc | APP_DEFAULT_MUC | null | Autocomplete MUC address (ex: conference.domain.ltd) 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: ['welcome@conference.domain.ltd', 'vip@conference.domain.ltd'] |
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) |
sso.endpoint | APP_SSO_ENDPOINT | false | Public endpoint for SSO (must be secured: do not expose it without an authentication mechanism) |
sso.jidHeader | APP_SSO_JID_HEADER | "jid" | Header containing JID after SSO request |
sso.passwordHeader | APP_SSO_PASSWORD_HEADER | "password" | Header containing password after SSO request |
| N/A | XMPP_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:
- xmpp.js (ISC)
- Vue.js (MIT)
- Pinia (MIT)
- Vue Router (MIT)
- Day.js (MIT)
- Bulma (MIT)
- Oruga (MIT)
- Font Awesome (MIT & SIL OFL 1.1)
License
This project is licensed under the GNU Affero General Public License v3.0 - see the LICENSE file for details