Strophe.js for XMPP: WebSockets, BOSH and Stream Management
Strophe.js is an XMPP library for JavaScript
At a glance
- What is it?
- 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.
- Who is it for?
- 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.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 6, 2026, and from our analysis. They are not legal advice.
Star history
- strophe/strophejs1,485 ★ · +0
| Repository | 2026-10-16 | 2026-11-06 |
|---|---|---|
| strophe/strophejs | 1.5k | 1.5k |
0 Stars in the last 21 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
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:
npm install strophe.jsFor 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:
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.
const conn = new Strophe.Connection('wss://example.org/xmpp-websocket');
conn.connect('[email protected]', '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="[email protected]" 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.
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:
<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:
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.
Editorial 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.
Frequently asked questions
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.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/strophe-strophejs)Star history chart for your README
[](https://hysenlabs.com/projects/strophe-strophejs)Was this useful?