# Strophe.js for XMPP: WebSockets, BOSH and Stream Management

> Strophe.js is a TypeScript XMPP client library for browser, Node.js and React Native applications. It supports WebSockets, BOSH/HTTP, several authentication mechanisms, stanza builders, connection recovery and a SharedWorker transport for sharing one connection across browser tabs.

**strophe/strophejs** — Strophe.js is an XMPP library for JavaScript

- Repository: https://github.com/strophe/strophejs
- Website: http://strophe.im/strophejs
- Stars: 1,485 · Forks: 359
- Language: TypeScript
- License: MIT
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/strophe-strophejs

## What Strophe.js Handles in a JavaScript XMPP Client

Strophe.js addresses the client-side work required to connect a JavaScript or TypeScript application to an XMPP service. It provides stanza creation, authenticated connection setup, incoming stanza handlers, request and response IQ processing, and transports for WebSockets and BOSH/HTTP. The intended audience includes developers building browser clients, Node.js services and React Native applications that communicate directly with XMPP infrastructure.

The library is most relevant when the application needs an XMPP identity rather than a simple internal messaging abstraction. Its documented examples cover one-to-one chat messages, presence announcements, roster pushes and IQ responses. It also includes support for server features that require explicit configuration, especially XEP-0198 Stream Management and SharedWorker-based connection sharing.

Strophe.js does not provide an application backend, user account system or message database. The README does not document server provisioning, federation policy, attachment storage or production XMPP administration. Those responsibilities must remain outside the library. Its scope is the client protocol layer: form stanzas, exchange them with an XMPP service and interpret the responses or events that arrive.

## Strophe.js Stanza Construction and Message Flow

The primary application flow starts with `Strophe.Connection`, which is created with an XMPP service endpoint. Calling `connect()` supplies a JID, password and a status callback. Once the callback reports `Strophe.Status.CONNECTED`, the application can register handlers, announce presence and send stanzas through `conn.send()`.

Strophe.js offers two stanza construction APIs. The recommended `stx` tagged template literal accepts XML-like markup and escapes interpolated values automatically. Arrays passed through interpolation are flattened, while `null` and `undefined` values are omitted. This makes it practical to generate repeated child elements without manually concatenating XML strings.

The older `$iq`, `$msg`, `$pres` and `$build` helpers remain supported. They use a chainable, jQuery-style API and are described as producing equivalent output to `stx`. They are a real alternative for codebases that already use those helpers, although new application code would normally favor the TypeScript-oriented template API.

Incoming stanzas are selected through `addHandler(callback, ns, name, type, id, from)`. A null selector field matches any value. The callback returns `true` to remain registered or `false` to be removed after handling one stanza. For IQ request and response exchanges, `sendIQ(stanza, onResult, onError, timeout)` associates the response with a callback and supplies a timeout path, reducing the need for application-managed IQ identifiers. The README does not specify the exact timeout failure object or callback invocation guarantees, so code that depends on those details needs verification against the generated API documentation.

## Installing Strophe.js and Sending the First XMPP Message

The npm installation command is:

```bash
npm install strophe.js
```

For Node.js, the README also requires `npm install @xmldom/xmldom ws` for DOM and WebSocket APIs. An ES module application can import the connection class and the recommended stanza builder from the same package:

```javascript
import { Strophe, stx } from 'strophe.js';
```

The following example connects to the documented WebSocket service, registers a chat handler after the connection reaches `CONNECTED`, sends presence, and then sends a message. Replace the endpoint and account values only with endpoints and credentials appropriate for the target service.

```javascript
const conn = new Strophe.Connection('wss://example.org/xmpp-websocket');

conn.connect('romeo@example.org', 'password', (status) => {
    if (status === Strophe.Status.CONNECTED) {
        conn.addHandler(onMessage, null, 'message', 'chat');
        conn.send(stx`<presence xmlns="jabber:client"/>`);
        conn.send(stx`
            <message to="juliet@example.org" type="chat" xmlns="jabber:client">
                <body>Art thou online?</body>
            </message>`);
    }
});
```

The message handler reads the `body` element and returns `true` to remain registered. If the target service returns a chat stanza containing a body, the callback writes the sender and body to the console.

```javascript
function onMessage(stanza) {
    const body = stanza.querySelector('body')?.textContent;
    if (body) console.log(`${stanza.getAttribute('from')} says: ${body}`);
    return true;
}
```

For a plain browser page without a build step, the README documents this UMD script and states that it exposes `Strophe`, `stx`, `$iq`, `$msg`, `$pres` and `$build` as globals:

```html
<script src="https://cdn.jsdelivr.net/npm/strophe.js/dist/strophe.umd.min.js"></script>
```

## WebSocket Resumption and Browser Tab Coordination

Strophe.js supports XEP-0198 Stream Management on WebSocket connections. The feature is disabled by default. Enabling it tells the library to obtain server acknowledgements for sent stanzas and to attempt session resumption after a connection is dropped. The stated purpose is to avoid losing sent stanzas during a resumable interruption.

Configuration is performed when constructing the connection:

```javascript
const conn = new Strophe.Connection(service, {
    enableStreamManagement: true,
    streamManagement: {
        maxUnacked: 5,
        requestResume: true,
    },
});
```

Here, `maxUnacked` requests acknowledgement every five sent stanzas, while `requestResume` asks the server for a resumable session. After connection, `conn.hasResumed()` reports whether the previous session was resumed. Applications can use that result to avoid repeating initialization such as fetching the roster or joining rooms. Resumable state is stored in `sessionStorage` by default, and the README documents a custom `streamManagement.storage` backend.

Resumption remains server-dependent. The feature is limited to WebSocket connections, and requesting a resumable session does not guarantee that a server will grant one. The library also cannot guarantee that every application operation will be idempotent after a failure, because acknowledgement and application-level processing are separate concerns.

A second browser-focused feature uses the `worker` connection option and `dist/shared-connection-worker.js`. Through SharedWorker, application tabs share one WebSocket connection. One tab acts as `primary`, while others act as `secondary` tabs and can be promoted if the primary disappears. This design can reduce duplicated connections, but it requires SharedWorker support and coordination logic. The README does not state fallback behavior for browsers without SharedWorker, so that compatibility boundary should be checked before choosing this transport.

## Distribution Boundaries, Authentication and Package Formats

The npm package is marked as an ES module in `package.json`, but it publishes several consumption formats. Its documented entry points include `dist/strophe.cjs` for CommonJS in Node.js, `dist/strophe.esm.js` for browser imports, `dist/strophe.node.esm.js` for Node.js imports, UMD browser files and TypeScript declarations under `dist/types`. This gives bundlers and non-bundled browser pages different distribution paths without changing the protocol API.

Authentication is broader than a single password login. The README lists SCRAM-SHA-1, SCRAM-SHA-256, SCRAM-SHA-384, SCRAM-SHA-512, PLAIN, EXTERNAL, OAuth Bearer, X-OAuth2 and Anonymous mechanisms. The actual mechanism accepted by a server is not determined by the library alone. Deployment also requires an appropriate endpoint and account state.

Password-based examples should not be copied into a public client unchanged. A browser application normally needs a flow that obtains credentials or tokens through an appropriate server-side process. The README does not define token storage, credential rotation or a complete OAuth application flow, so those concerns are outside its documented scope.

For environments where XMPP is undesirable at the browser layer, the alternative is a backend-mediated chat API: the backend would hold the XMPP connection and expose an application-specific interface to browser code. That approach changes the trust and deployment model rather than reproducing Strophe.js features. The README also documents a Node-only XEP-0114 external-component transport for gateways and bots; an application-specific browser API would still need to be built separately.

## Maintenance, Upgrades and the MIT Package Boundary

The repository is not archived. Its last push was on 2026-08-14, and `package.json` reports version `5.0.0`. The repository release history lists v5.0.0 on 2026-07-21, followed by v4.1.2 on 2026-07-12 and v4.1.1 on 2026-07-08. The ordering shows that the v4 maintenance releases were published around the same period as v5.0.0, but the README does not document migration differences between those lines.

Upgrading from v4 to v5 therefore requires more care than replacing a patch release. The repository contains `CHANGELOG.md` and `RELEASE_CHECKLIST.md`, but their contents are not included in the README. Consumers should inspect those files before changing a production dependency, particularly if they rely on classic builders, Node.js module loading, worker behavior or Stream Management introduced in v4.1.0.

The declared license is MIT. The npm package includes `LICENSE.txt`, so the license text is available alongside the published files. That declaration describes the project's licensing choice, but applications still need to account for their own notices, server configuration and third-party services. Browser delivery may also involve packaging considerations because the published package includes source, distribution files, changelog, license and README.

## Conclusion

Browser, Node.js and React Native developers building direct XMPP clients should evaluate Strophe.js, especially when typed code, browser delivery or XEP-0198 recovery matter. For a server-side gateway, evaluate its Node-only XEP-0114 external-component transport and the server's component listener requirements. Before adoption, verify `sendIQ()` behavior, the selected transport, browser worker requirements, authentication support on the target server and the security implications of handling XMPP passwords in client code.

## FAQ

### How do I install Strophe.js in a JavaScript project?

Run `npm install strophe.js`, then import the connection and stanza APIs with `import { Strophe, stx } from 'strophe.js';`.

### Does Strophe.js support XMPP over WebSockets and BOSH?

Yes. The README states that it supports XMPP over WebSockets under RFC 7395 and BOSH/HTTP under XEP-0124 and XEP-0206.

### How does Strophe.js resume a dropped XMPP connection?

On WebSocket connections, set `enableStreamManagement: true` and configure `requestResume: true`. After connecting, use `conn.hasResumed()` to determine whether the previous session was resumed.

## Sources

- [License: MIT](https://github.com/strophe/strophejs/blob/master/LICENSE)
- [Project website](http://strophe.im/strophejs)
- [README](https://github.com/strophe/strophejs/blob/master/README.md)
- [Releases](https://github.com/strophe/strophejs/releases)
- [strophe/strophejs on GitHub](https://github.com/strophe/strophejs)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/strophe-strophejs
