Create an HTML5 chat app on Bluemix with Node.js, Redis, and


Until recently, creating a web-based chat app was not a simple project. The HTTP protocol makes web-based chat difficult to implement because its request-response architecture does not lend itself well to the constantly updating nature of chat. This article shows that this has all changed, thanks to HTML5 and the WebSocket API. You'll learn how to use the library to create a real-time chat app in no time at all.

The app runs on Bluemix, a platform that makes it a breeze to push your apps out to the world.

On the server side, the app described in this article is powered by Node.js, the popular JavaScript server-side runtime powered by the V8 JavaScript engine. It serves regular HTTP requests using the Express framework and the Jade template engine. Most of the heavy lifting for this app is handled by, but it's easy to implement on both the server and the client. The app also caches the 100 most recent messages in a Redis data store. The app runs on Bluemix, a platform that makes it a breeze to push your apps out to the world.

Run the appGet the code

What you'll need to build your app

  • A basic familiarity with HTML, CSS, and JavaScript
  • Node.js
  • Redis
  • A Bluemix account
  • The Bluemix command-line interface (cf)

Note: The complete source code for the application is available from IBM DevOps Services. For brevity, the article does not include full source code listings. Download the source code (click Get the code above) so you can follow along.

Step 1. Create the app

Create a directory for the app on your computer and add the package.json file.

      "name": "bluemixchat",
      "version": "0.0.1",
      "private": true,
      "scripts": {
        "start": "node server.js"
      "dependencies": {

Install the required npm modules:

  • Express
  • Jade
  • Redis

Install these modules using npm install --save express jade redis

This command installs the npm modules (and any other modules that they are dependent on) into your project's node_modules subdirectory, and the command automatically adds these modules as dependencies in your package.json file. As shown below, the next step is to get a bare-bones Express app (server.js) up and running.

    // Startup Express App
    var express = require('express');
    var app = express();
    app.listen(process.env.PORT || 3000);

    // Configure Jade template engine
    var path = require('path');
    app.set('views', path.join(__dirname, 'views'));
    app.set('view engine', 'jade');
    app.use(express.static(path.join(__dirname, 'public')));

    // handle HTTP GET request to the "/" URL
    app.get('/', function(req, res) {

In the previous code listing, the app handles incoming requests for the / URL and renders a view named index. Create that view now. First, create a subdirectory named views, and in it, add the file index.jade. The contents of this file are shown in the following code listing.

Note: This code loads a stylesheet to style the app from the public/stylesheets subdirectory. This stylesheet file is not covered in the article. The stylesheet file that contains the CSS code is in the code you downloaded from DevOps Services.

    doctype html
        title Bluemix Chat
        meta(name='viewport', content='initial-scale=1.0, width=device-width, \
         height=device-height, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no')
        link(rel='stylesheet', href='//')
        link(rel='stylesheet', href='/stylesheets/style.css')    
        h1 Bluemix Chat
          input(id='msg', autocomplete='off', autofocus)
          button(type='submit') Send

The Jade template engine offers a shorthand way of defining HTML pages. Note that it uses white space to determine the structure of the document. Make sure you don't mix spaces and tabs, and be very careful with how you indent your code.

You should now be able to run your app. At the command line in your project directory, run npm start.

This command runs a web server on your machine on port 3000. To see the app in action, point your browser to http://localhost:3000. You should see a window similar to the following image.

Screen capture shows                     shell Bluemix chat
Screen capture shows shell Bluemix chat

Step 2. Push the app to Bluemix

To deploy the app to Bluemix, use the command-line interface tool, cf. If you don't have this, go to the project's GitHub page for information on how to install it. Alternatively, you can create apps and services from the Bluemix dashboard, but you need the cf tool to deploy your app; therefore, I use it to do everything in this article.

To connect to the Bluemix API and log in using your Bluemix account, run the following commands:

    cf api
    cf login

Provide your email address and password after you enter the second command.

Warning: Enter unique names and host names for your application when you deploy it to Bluemix. If you use the names provided in these examples, you get errors.

You can now deploy this on Bluemix using cf push bluemixchat.

When the app has deployed, a message indicates the app is started and gives the URL to the app. To test that the app is working, point your browser to The next step is to enable real-time messaging using

Step 3. Update clients in real-time using is an npm module that makes it really simple to build applications that use HTML5 WebSockets on the server and the client. When you bind to your Node.js app, it automatically serves a client-side JavaScript library at the URL / you can use to push and listen for new messages from the server.

To add the server to the Express app, find the following line in the server.js file: app.listen(process.env.PORT || 3000);. Replace this line with the following code.

    var http = require('http').Server(app);
    var io = require('')(http);
    http.listen(process.env.PORT || 3000);

This code loads the HTTP module and binds the server to it. The code listens for incoming requests on port 3000 or the port defined in the PORT environment variable for the current process. When the app is deployed to Bluemix, the PORT setting defines what port to listen to.

Next, add some code to handle the various events in the chat app and to send messages to connected clients using At the end of the server.js file, add the following code.

    // listen for messages
    io.on('connection', function(socket) {  
      // When a message is received, broadcast it
      // to all users except the originating client
      socket.on('msg', function(data) {        
        socket.broadcast.emit('msg', data);        

      // When a user joins the chat, send a notice
      // to all users except the originating client
      socket.on('join', function(nickname) {
        // Attach the user's nickname to the socket
        socket.nickname = nickname;
        socket.broadcast.emit('notice', nickname + ' has joined the chat.');

      // When a user disconnects, send a notice
      // to all users except the originating client
      socket.on('disconnect', function() {
        socket.broadcast.emit('notice', socket.nickname + ' has left the chat.');

Now that the server-side code is complete, add code on the client-side to interact with Add the following code to the end of the file views/index.jade. Note that this code should be indented within the body element in the Jade template. If it's not, you might experience problems.


This code loads jQuery from a Content Delivery Network (CDN), from the standard location the server makes it available from, and a client.js file to be stored in the public/javascripts directory in your app. Create this file now. Its contents are shown below.

    $(document).ready(function() {
      var socket = io(), nickname, msgList = $('#messages');

      // Check if nickname stored in localStorage
      if('localStorage' in window && localStorage.getItem('nickname')) {
        nickname = localStorage.getItem('nickname');
      } else {
        // If not in localStorage, prompt user for nickname
        nickname = prompt('Please enter your nickname');
        if('localStorage' in window) {
          localStorage.setItem('nickname', nickname);

      // Send message to server that user has joined
      socket.emit('join', nickname);

      // Function to add a message to the page
      var newMessage = function(data) {
        var who = $('<div class="who">').text(data.nickname),
            when = $('<div class="when">').text(new Date().toString().substr(0, 24)),
            msg = $('<div class="msg">').text(data.msg),
            header = $('<div class="header clearfix">').append(who).append(when),
            li = $('<li>').append(header).append(msg);    


      // Handle the form to submit a new message
      $('form').submit(function(e) {
        var msgField = $('#msg'),        
            data = { msg: msgField.val(), nickname: nickname, when: new Date() };

        // Send message to server
        socket.emit('msg', data);
        // Add message to the page
        // Clear the message field

      // When a message is received from the server
      // add it to the page using newMessage()
      socket.on('msg', function(data) { newMessage(data); });

      // When a notice is received from the server
      // (user joins or disconnects), add it to the page
      socket.on('notice', function(msg) {
        msgList.prepend($('<div class="notice">').text(msg));

This code checks whether the user has already entered a nickname by looking up the browser's localStorage store. If not, the code prompt the user to enter one. The code stores the nickname in localStorage for future use. When the page loads, a message is sent to to specify that a new user has joined. When the message form is submitted, the app adds the message to the page and sends it to the server. In the last step, the app listens for two events, msg and notice, and updates the page any time it receives data on these events.

Run the app again to enter messages and see them displayed on the screen. You can launch another browser and connect to the app to send messages on one browser and see them on the other. Try it with a few browsers or devices — you've just built a functional chat app.

Next, learn how to store these messages using a Redis data store.

Step 4. Store message history in Redis

When you use the app as it stands, notice that when you refresh the page, all the chat history is lost. If you're using the app on a mobile device, this creates an additional problem because mobile users tend to use apps such as this intermittently. When their device locks and they reopen the browser, it might refresh the page, which causes the history to be lost.

To resolve this, store the chat history in a data store. The Redis store makes it a breeze to store data such as key-value pairs, lists, etc. It is much faster than a regular database because it stores data in memory rather than on disk. It is perfect for caching data, which makes it a great fit for storing the message history in the chat app.

Make sure that Redis is running on your local machine. (Typically, this is done by running the command redis-server). Next, find the following line in the file server.js: http.listen(process.env.PORT || 3000);. Insert the following code below this line.

    // Configure Redis client connection
    var redis = require('redis');
    var credentials;
    // Check if we are in Bluemix or localhost
    if(process.env.VCAP_SERVICES) {
      // On Bluemix read connection settings from
      // VCAP_SERVICES environment variable
      var env = JSON.parse(process.env.VCAP_SERVICES);
      credentials = env['redis-2.6'][0]['credentials'];
    } else {
      // On localhost just hardcode the connection details
      credentials = { "host": "", "port": 6379 }
    // Connect to Redis
    var redisClient = redis.createClient(credentials.port,;
    if('password' in credentials) {
      // On Bluemix we need to authenticate against Redis

Note: When you deploy the app to Bluemix later, it will read the connection settings for Redis from the VCAP_SERVICES environment variable. This code connects and authenticates against the Redis server.

Update the server app to push new messages to Redis when they are received. Find the following block:

    socket.on('msg', function(data) {        
      socket.broadcast.emit('msg', data);        

At the start of the anonymous function, add the following lines.

    redisClient.lpush('messages', JSON.stringify(data));
    redisClient.ltrim('messages', 0, 99);

This code pushes the latest message to the messages list in Redis, and it then trims the list to the 100 most recent items (if it has more than 100 items). The final piece of the puzzle is to look for existing messages in Redis when the client launches. To do this, find the following block:

    app.get('/', function(req, res) {

Replace this block with the following code.

    app.get('/', function(req, res) {
      // Get the 100 most recent messages from Redis
      var messages = redisClient.lrange('messages', 0, 99, function(err, reply) {
        if(!err) {        
          var result = [];
          // Loop through the list, parsing each item into an object
          for(var msg in reply) result.push(JSON.parse(reply[msg]));
          // Pass the message list to the view
          res.render('index', { messages: result });    
        } else res.render('index');

This code gets the 100 most recent items in the Redis list messages, loops through them, and parses them as JSON into JavaScript objects. It then passes an array of these objects to the view. Open the file views/index.jade and nest the following code within the ul#messages element.

    - for(var i=0,ln=messages.length;i<ln;i++)      
          .who= messages[i].nickname
          .when= new Date(messages[i].when).toString().substr(0, 24)
        .msg= messages[i].msg

Launch the app again and send some messages. Notice that when you reload the page, the message history is restored. The app doesn't currently store user join and disconnect notices, but you can easily extend it to do this. As a last step, get Redis set up on Bluemix and push the final product out to the world.

Step 5. Create and bind to a Redis service on Bluemix

To push the latest changes to Bluemix, provision a Redis service instance and bind it to your app. To create the service, use cf create-service redis 100 bmcredis.

Change the database name (bmcredis in the previous command) to something unique. For the app to be able to connect to the database, you need to bind it: cf bind-service bluemixchat bmcredis.

Restart your app for the binding to become active. Push your changes to Bluemix using cf push.

Congratulations! You have now built a chat application using Node.js, Redis, and, and you have deployed it to Bluemix. You can see that the app is up and running.

Screen captures                     show Bluemix chat in action
Screen captures show Bluemix chat in action


The app you have built is a fully functional chat app, but there are many ways you can extend it. You can enable users to change their nicknames or to see a list of other connected users. You can add support for multiple rooms, private messaging, and much more. Because you've deployed this app on Bluemix, any features you add can be deployed with a simple cf push command. It doesn't get much easier than that.

Downloadable resources

Related topics


Sign in or register to add and subscribe to comments.

Zone=Web development, Cloud computing
ArticleTitle=Create an HTML5 chat app on Bluemix with Node.js, Redis, and