XMPP real-time chat in React Native

Sep 18, 2018 · 4 min read

Here we are going to explain how to use XMPP protocol for real-time chat in React Native apps.

Create React Native App

To create a React Native app — use the Getting Started guide for reference:

npm install -g create-react-native-appcreate-react-native-app AwesomeProject cd AwesomeProject npm start

So we have a skeleton project and now we can add an XMPP library dependency into it.

Add XMPP lib depdendency

Here we are going to use xmpp.js lib since the same code base can work on multiple environments — Node.js, React Native, Native Script.

The npm package of this lib is not updated properly (last update published a year ago), so we are forced to use the latest master code which is actually the most stable version of the lib:

git clone git@github.com:xmppjs/xmpp.js.git
cd xmpp.js

Prepare App UI

Our app will have 2 buttons: to connect to XMPP server and to send a message. Also it will contain a text view to which we will post statuses about connection and messages.

Here is the whole content of our skeleton App.js file:

import React from 'react';
import { StyleSheet, Text, TouchableHighlight, View, ScrollView } from 'react-native';
export default class App extends React.Component {
constructor(props) {
this.state = {
output: ''
onStartConnect() { } onSendMessage() { } render() { var buttons = (
<View style={styles.container}>
<Text style={styles.buttonText}>
Connect to XMPP server (login)
<Text style={styles.buttonText}>
Send a message
return (
<View style={styles.container}>
<Text style={styles.output_result}>
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
button: {
height: 50,
backgroundColor: '#48BBEC',
alignSelf: 'stretch',
marginTop: 10,
justifyContent: 'center',
buttonText: {
fontSize: 22,
color: '#FFF',
alignSelf: 'center'
output_result: {
color: '#000',
marginTop: 20,

Initialise XMPP client

Now open App.js file and initialise an XMPP client:

var client = require('./xmpp.js/packages/client');

Also we need to connect a base-64 dependency since this lib uses it inside:

In your package.js do the following:

"dependencies": {

"base-64": "0.1.0"

Then do npm install in terminal.

Then add the following code in your App.js:

var base64 = require('base-64');
global.btoa = base64.encode;
global.atob = base64.decode;

Implement the ‘Connect to Server’ logic

Modify a constructor and add the following code:

constructor(props) {
this.state = {
output: ''
this.xmppClientListeners = [];
this.xmppClient = XMPP.xmpp().client;
// you XMPP server endpoints
this.XMPPServerOptions = {uri: 'wss://chat.connectycube.com:5291',
domain: 'chat.connectycube.com'};
// Demo user credentials (25045–19@chat.connectycube.com)
this.XMPPUserCredentials = {jidLocalPart: '25045–19',
password: 'securepwd123'};

Here we initialise an xmppClient and also setup XMPP server endpoint and a demo user credentials.

Next, we implement a connect method which will initiate a connection to XMPP server with above demo user:


Next, implement an addListeners method that will setup all needed connection callbacks e.g. for success connect, for incoming messages etc.:

addListeners() {
var self = this;
var removeAllListeners = function(){
self.xmppClientListeners = [];
removeAllListeners(); const callbackConnect = function() {
this.xmppClient.on('connect', callbackConnect);
this.xmppClientListeners.push({name: 'connect',
callback: callbackConnect});
const callbackOnline = function(jid) {
this.xmppClient.on('online', callbackOnline);
this.xmppClientListeners.push({name: 'online',
callback: callbackOnline});
const callbackStatus = function(status, value) {
// self.log('status: ' + status);
this.xmppClient.on('status', callbackStatus);
this.xmppClientListeners.push({name: 'status',
callback: callbackStatus});
// this.xmppClientReconnect.on('reconnecting', function() {
// Utils.DLog('[Chat]', 'RECONNECTING');
// });
// this.xmppClientReconnect.on('reconnected', function() {
// Utils.DLog('[Chat]', 'RECONNECTED');
// });
const callbackStanza = function(stanza) {
// console.log('stanza', stanza.toString())
// after 'input' and 'element' (only if stanza, not nonza)
if (stanza.is('presence')) {
self.log("On PRESENCE: " + stanza);
} else if (stanza.is('iq')) {
self.log("On IQ: " + stanza);
} else if(stanza.is('message')) {
self.log("On MESSAGE: " + stanza);
this.xmppClient.on('stanza', callbackStanza);
this.xmppClientListeners.push({name: 'stanza',
callback: callbackStanza});
const callbackError = function(err) {
self.log('ERROR:', err);
this.xmppClient.on('error', callbackError);
this.xmppClientListeners.push({name: 'error',
callback: callbackError});
// this.xmppClient.on('element', function(element) {
// // console.log('element', element.toString())
// // after 'input'
// });
// this.xmppClient.on('send', function(element) {
// // console.log('send', element.toString())
// // after write to socket
// });
// this.xmppClient.on('outgoing', function(element) {
// // before send
// // console.log('outgoing', element.toString())
// });
const callbackOutput = function(str) {
// self.log('SENT:', str);
this.xmppClient.on('output', callbackOutput);
this.xmppClientListeners.push({name: 'output',
callback: callbackOutput});
const callbackInput = function(str) {
// self.log('RECV:', str);
this.xmppClient.on('input', callbackInput);
this.xmppClientListeners.push({name: 'input',
callback: callbackInput});
const callbackAuthenticate = function(authenticate) {
return authenticate(self.XMPPUserCredentials.jidLocalPart,
this.xmppClient.handle('authenticate', callbackAuthenticate);
this.xmppClientListeners.push({name: 'authenticate',
callback: callbackAuthenticate});
this.setState({output: this.state.output + "\n" + text})

And finally we can implement an onStartConnect button callback where we can initiate a connection & authorisation process with the XMPP server:

onStartConnect() {

Now you can run the app, press on Connect to XMPP server (login) button and check it. You should see something like this:

Demo of XMPP login to XMPP server

Implement ‘Send a Message’ functionality

Now we will implement an onSendMessage method which will build a message and send it to current user:

onSendMessage() {
// he we send a message for the same user
var stanzaParams = {
from: this.XMPPUserCredentials.jidLocalPart + "@" +
to: this.XMPPUserCredentials.jidLocalPart + "@" +
type: ‘chat’,
id: Math.floor(Math.random() * Math.floor(999999999))
var messageStanza = XMPP.xml("message", stanzaParams);
messageStanza.c('body', {
xmlns: 'jabber:client',
}).t("Hello Amigo").up();

Then you will receive the message using above callback methods.


The complete source code of the app is located at GitHub repo https://github.com/ConnectyCube/react-native-xmpp-demo

Need a complete cross-platform real-time Chat app?

ConnectyCube provides a complete ConnectyCube React Native Chat samples as an example.

All the modern Chat features are supported:

  • 1–1 messaging
  • Group messaging
  • Cross-platform
  • Sent/Delivered/Read statuses
  • ‘Is typing’ statuses
  • File attachments
  • Automatic push notifications to offline users
  • Contact list
  • Black list
  • End-to-end Encryption via additional plugins
  • Chat moderation (via Trust & Safety (TnS) feature)

Sign Up today

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store