• Home
  • blog
  • Building a Real-time Chat App with Sails.js

Building a Real-time Chat App with Sails.js

If you’re a developer who currently uses frameworks such as Django, Laravel or Rails, you’ve probably heard about Node.js. You might already be using a popular front-end library such as Angular or React in your projects. By now, you should be thinking about doing a complete switchover to a server technology based on Node.js.

However, the big question is where to start. Today, the JavaScript world has grown at an incredibly fast pace in the last few years, and it seeming to be ever expanding.

If you’re afraid of losing your hard-earned programming experience in the Node universe, fear not, as we have Sails.js.

Sails.js is a real-time MVC framework designed to help developers build production-ready, enterprise-grade Node.js apps in a short time. Sails.js is a pure JavaScript solution that supports multiple databases (simultaneously) and multiple front-end technologies. If you’re a Rails developer, you’ll be happy to learn that Mike McNeil, the Sails.js founder, was inspired by Rails. You’ll find a lot of similarities between Rails and Sails.js projects.

In this article, I’ll teach you the fundamentals of Sails.js, by showing you how to build a simple, user-friendly chat application. The complete source code for the sails-chat project can be found in this GitHub repo.

Sails Chat App


Before you start, you need at least to have experience developing applications using MVC architecture. This tutorial is intended for intermediate developers. You’ll also need at least to have a basic foundation in these:

To make it practical and fair for everyone, this tutorial will use core libraries that are installed by default in a new Sails.js project. Integration with modern front-end libraries such as React, Vue or Angular won’t be covered here. However, I highly recommend you look into them after this article. Also, we won’t do database integrations. We’ll instead use the default, local-disk, file-based database for development and testing.

Project Plan

The goal of this tutorial is to show you how to build a chat application similar to Slack, Gitter or Discord.

Not really! A lot of time and sweat went into building those wonderful platforms. The current number of features developed into them is quite huge.

Instead, we’ll build a minimum viable product version of a chat application which consists of:

  • single chat room
  • basic authentication (passwordless)
  • profile update.

I’ve added the profile feature as a bonus in order to cover a bit more ground on Sails.js features.

Installing Sails.js

Before we start installing Sails.js, we need first to set up a proper Node.js environment. At the time of writing, the latest stable version currently available is v0.12.14. Sails.js v1.0.0 is also available but is currently in beta, not recommended for production use.

The latest stable version of Node I have access to is v8.9.4. Unfortunately, Sails.js v0.12 doesn’t work properly with the current latest LTS. However, I’ve tested with Node v.7.10 and found everything works smoothly. This is still good since we can use some new ES8 syntax in our code.

As a JavaScript developer, you’ll realize working with one version of Node.js is not enough. Hence, I recommend using the nvm tool to manage multiple versions of Node.js and NPM easily. If you haven’t done so, just purge your existing Node.js installation, then install nvm to help you manage multiple versions of Node.js.

Here are the basic instructions of installing Node v7 and Sails.js:

# Install the latest version of Node v7 LTS
nvm install v7

# Make Node v7 the default
nvm default alias v7

# Install Sails.js Global
npm install -g sails

If you have a good internet connection, this should only take a couple of minutes or less. Let’s now go ahead and create our new application using the Sails generator command:

# Go to your projects folder
cd Projects

# Generate your new app
sails generate new chat-app

# Wait for the install to finish then navigate to the project folder
cd chat-app

# Start the app
sails lift

It should take a few seconds for the app to start. You need to manually open the url http://localhost:1337 in your browser to see your newly created web app.

Sails lift

Seeing this confirms that we have a running project with no errors, and that we can start working. To stop the project, just press control + c at the terminal. User your favorite code editor (I’m using Atom) to examine the generated project structure. Below are the main folders you should be aware of:

  • api: controllers, models, services and policies (permissions)
  • assets: images, fonts, JS, CSS, Less, Sass etc.
  • config: project configuration e.g. database, routes, credentials, locales, security etc.
  • node_modules: installed npm packages
  • tasks: Grunt config scripts and pipeline script for compiling and injecting assets
  • views: view pages — for example, EJS, Jade or whatever templating engine you prefer
  • .tmp: temporary folder used by Sails to build and serve your project while in development mode.

Before we proceed, there are a couple of things we need to do:

  • Update EJS package. If you have EJS 2.3.4 listed in package.json, you need to update it by changing it to 2.5.5 immediately. It contains a serious security vulnerability. After changing the version number, do an npm install to perform the update.
  • Hot reloading. I suggest you install sails-hook-autoreload to enable hot reloading for your Sails.js app. It’s not a perfect solution but will make development easier. To install it for this current version of Sails.js, execute the following:
npm install [email protected] --save

Installing Front-end Dependencies

For this tutorial, we’ll spend as little time as possible building an UI. Any CSS framework you’re comfortable with will do. For this tutorial, I’ll go with the Semantic UI CSS library.

Sails.js doesn’t have a specific guide on how to install CSS libraries. There are three or more ways you can go about it. Let’s look at each.

1. Manual Download

You can download the CSS files and JS scripts yourself, along with their dependencies. After downloading, place the files inside the assets folder.

I prefer not to use this method,
as it requires manual effort to keep the files updated. I like automating tasks.

2. Using Bower

This method requires you to create a file called .bowerrc at the root of your project. Paste the following snippet:

"directory" : "assets/vendor"

This will instruct Bower to install to the assets/vendor folder instead of the default bower_components folder. Next, install Bower globally, and your front-end dependencies locally using Bower:

# Install bower globally via npm-
npm install -g bower

# Create bower.json file, accept default answers (except choose y for private)
bower init

# Install semantic-ui via bower
bower install semantic-ui --save

# Install jsrender
bower install jsrender --save

I’ll explain the purpose of jsrender later. I thought it best to finish the task of installing dependencies in one go. You should take note that jQuery has been installed as well, since it’s a dependency for semantic-ui.

After installing, update assets/style/importer.less to include this line:

@import '../vendor/semantic/dist/semantic.css';

Next include the JavaScript dependencies in tasks/pipeline.js:

var jsFilesToInject = [

// Load before everything else

// Vendor dependencies

// Dependencies like jQuery or Angular are brought in here

// All of the rest of your client-side JS files
// will be injected here in no particular order.

When we run sails lift, the JavaScript files will automatically be injected into views/layout.ejs file as per pipeline.js instructions. The current grunt setup will take care of injecting our CSS dependencies for us.

Important: add the word vendor in the .gitignore file. We don’t want vendor dependencies saved in our repository.

3. Using npm + grunt.copy

The third method requires a little bit more effort to set up, but will result in a lower footprint. Install the dependencies using npm as follows:

npm install semantic-ui-css jsrender --save

jQuery will be installed automatically, since it’s also listed as a dependency for semantic-ui-css. Next we need to place code in tasks/config/copy.js. This code will instruct Grunt to copy the required JS and CSS files from node_modules to the assets/vendor folder for us. The entire file should look like this:

module.exports = function(grunt) {

grunt.config.set('copy', {
  dev: {
    files: [{
      expand: true,
      cwd: './assets',
      src: ['**/*.!(coffee|less)'],
      dest: '.tmp/public'
    //Copy JQuery
      expand: true,
      cwd: './node_modules/jquery/dist/',
      src: ['jquery.min.js'],
      dest: './assets/vendor/jquery'
    //Copy jsrender
      expand: true,
      cwd: './node_modules/jsrender/',
      src: ['jsrender.js'],
      dest: './assets/vendor/jsrender'
    // copy semantic-ui CSS and JS files
      expand: true,
      cwd: './node_modules/semantic-ui-css/',
      src: ['semantic.css', 'semantic.js'],
      dest: './assets/vendor/semantic-ui'
    //copy semantic-ui icon fonts
      expand: true,
      cwd: './node_modules/semantic-ui-css/themes',
      src: ["*.*", "**/*.*"],
      dest: './assets/vendor/semantic-ui/themes'
  build: {
    files: [{
      expand: true,
      cwd: '.tmp/public',
      src: ['**/*'],
      dest: 'www'


Add this line to assets/styles/importer.less:

@import '../vendor/semantic-ui/semantic.css';

Add the JS files to config/pipeline.js:

// Vendor Dependencies

Finally, execute this command to copy the files from node_modules the assets/vendor folder. You only need to do this once for every clean install of your project:

grunt copy:dev

Remember to add vendor to your .gitignore.

Testing Dependencies Installation

Whichever method you’ve chosen, you need to ensure that the required dependencies are being loaded. To do this, replace the code in view/homepage.ejs with the following:

<h2 class="ui icon header">
<i class="settings icon"></i>
<div class="content">
  Account Settings
  <div class="sub header">Manage your account settings and set e-mail preferences.</div>

After saving the file, do a sails lift. Your home page should now look like this:


Always do a refresh after restarting your app. If the icon is missing or the font looks off, please review the steps carefully and see what you missed. Use the browser’s console to see which files are not loading. Otherwise, proceed with the next stage.

Continue reading %Building a Real-time Chat App with Sails.js%