The Future of ExpressJS and Alternatives

Ado Kukic

Time-saving synchronized browser testing

The rise of responsive web development (and web development in general) has sparked a tremendous surge around workflow automation. As a result of this, a plethora of build tools such a GruntJS and Gulp have become an integral part of so many developers lives. Although these tools are powerful, sometimes developers are looking for a simpler route in which they can access beneficial features, such as a live-reload server, without any configuration involved.

Luckily for them, BrowserSync was created, which allow users to access a development server with real-time live-reload capabilities. Better yet, it provides this without having to write out any code. Although there are a number of popular npm packages that provide this technology, it's clearly evident that BrowserSync is a leg above the competition. That being said, let's begin learning about BrowserSync and all of the features that make it so special.

Browsersync Homepage

Install BrowserSync

To use the BrowserSync command-line tool, it first needs to be installed via NPM.

npm install -g browser-sync

Once installed, users have access to the browser-sync command line tool. This tool can be used to start a server and watch specific files for any changes. To get a better understanding of this, let's consider a project with the following folder structure.

|-- HTML5-Starter
    |-- public
        |-- index.html
        |-- css
            |-- main.css
            |-- normalize.css
        |-- js
            |-- main.js
            |-- plugins.js
     |-- server

Given that browser-sync has been installed globally on your computer, a server can be started by running the following command:

$ HTML5-Boilerplate ~ browser-sync start --server "public" --files "public/**/*.css, public/**/*.js, *.html"

By analyzing this code, we see that we need to specify a number of things for browser-sync to work properly.

  1. First, we start browser-sync with browser-sync start.
  2. Immediatelly following this, we use --server "public" to tell browser-sync to start a server for us in the public directory.
  3. Lastly, we use the --files flag to specify the files which we want browser-sync to watch. In this example, we are using the method of globbing with the * symbol to watch for changes in any css, js, or html files from their respective directives inside of public. Another important aspect of this command are the comma's which separate the files we are watching. They make specifying files extremely easy, and browser-sync will not work if they are not present.

Below, I have included a screenshot of what the outputted result of this command looks like on my computer. Let's take a look at this image and gain an understanding of what's going on.

Browsersync CLI Output

Sync across all devices!

The first thing we see are two different access urls: one for viewing our project and one for viewing browser-sync's user-interface. Additionally, we see that browser-sync provides us with local and external URLs for both of these ports. As one might guess, the local url can be accessed directly on the device where Browsersync is running. On the other hand, the external URL can be accessd by any browser, granted that it is connected to the same network, and this is one of the things that makes Browsersync so powerful.

By taking a look at the short video below, we can see an example of how this works.

Basic Sync Video

In the video above, we see that simultaneous browsers being used to view a web page. When a change is made inside any of the files that are being watched, Browsersync will reflect the changes right onto the webpage. By default, browsersync will refresh the page when new HTML is added, however any css code will be immediately injected into the Browser, thus eliminating the need for the browser to refresh.

As a result of this, we are able to change our code instantly as shown in the example above.

To achieve this, browsersync utilizes the real-time capabilties of, thus providing users with real-time synchronization across all connected devices. Moreover, any changes we make inside our text-editor will not only be reflected in our browser, but also on any tablet or smart-phone that is accessing the project's external url.

Event Synchronization

In addition to proving stunning live-reload capabilties, Browsersync extends it's features into the realm of user interactions. By default, browsersync operates in "ghostMode". While in this mode, the scrolling of one page is going to be reflected throughout all connected devices and the same goes for click events and user input. Because of this we can test our projects across different browsers without ever actually having to go into each browser to do so.

Below, I have recorded a video of this event synchronization. Specifically, you will see that the modal dialog will pop up on both windows when clicked. Additionally, we can see an example of how any input typed into a form is reflected across any of web browsers that are connected.

Scrolls, Click, Form events

Upon seeing this video, we can see further how a web application works in Chrome, Safari, FireFox, Internet Explorer, etc. without having to manually go into each application. (That's right! BrowserSync supports Internet Explorer all the way back to IE7!) From there, we are more easily able to deal with inconsistencies among browsers on both desktop and mobile.

Once you realize this, it makes sense that their motto is "Time-saving synchronized browser-testing".

UI Port

As if the aforementioned capabilities were not ample enough, Browersync supplies a User Interface for developers, and a solid one at that. For the sake of this lesson, I have included a number of screenshots that further show the features Browsersync grants its users.

BrowserSync UI

Overview Page

The overview page provides users with some helpful information about the current dev server. It provides details about the port this project is using and the directory that is being served. What I find most interesting is the Concurrent Connections section on the bottom. Here, we can check out all of the different devices that are accessing Browsersync's server .

Browsersync UI - Landing Page

Sync Options

This section of the the UI allows us to disable different features in Browsersync. Specifically, these options define which actions will be synchronized across devices or not. As we learned earlier, BrowserSync comes with ghostMode enable, therefore all of these options are turned on, however we could easily change this by toggling the switches shown below.

Browsersync UI - Sync Options

URL History

The last part of the Browser-Sync UI I want to discuss deals with the URL history. When using Browser-Sync, any URLs that have been visited will be recorded. In the example below, we see that the following paths have been followed: / and /projects. We can use these URLs to navigate to specific URLs on our computer, however the fun doesn't stop there! Furthermore, we can use the sync all button to send all instances viewing the project to a specific route!

Browsersync UI - URL History

Need to finish editing

Customizing Browsersync

We already know that BrowserSync provides a standalone command-line tool, and a very solid one at that; however, we could configure BrowserSync using its API. Additionally, this API allows us to configure the files we want browser-sync to watch, and it even allows us create multiple browser-sync processes using the .create() method.

In many cases, people want browser-sync to inject any new HTML into our project, just like it does with CSS code. Luckily for those people, we can achieve this functionality using browsersync alongside the bs-html-inject package (which can be installed via NPM).

Below, we can see an example of how we can use browsersync's API, which you can learn more about via [this link](). As you can see, this set up is incredibly simple.

var bs = require('browser-sync').create();
    server: "public",
    files: ["public/css/*.css"],
    plugins: [
            module: "bs-html-injector",
            options: {
                files: ["public/*.html"]
  1. First, we imported browser-sync like we would any other node module. Once imported, we then use the .create() method to create a new browser-sync instance.
  2. Next, we utilize browser-sync's .init method to initialize our configuring.
    • While inside this .init() method, we specify the folder we want to serve, as well as the files we want to run on, similar to how we did it with the browsersync command-line tool.
    • After defining our initial configuration, we then specify the plug-ins we want to integrate browsersync with. In our case, we are using the bs-html-inject module, and we are having it watch our index.html file in our public directory.

Now, if we were to run node bs.js in our terminal, Browersync will start a server for us with the specified configuration. If we take a look below, we can see one final video in which I am using this configuration to start a server; and as you can see, any new HTML is directly injected into the page without the need to refresh the browser!

HTML Injector Plugin Video


Hopefully by now you have gained a firm understanding of Browsersync and why it is such an effective tool! As you probably assumed, Browsersync can be used with tools such as Gulp, Grunt, and Webpack, so anyone who is interested in that can learn more by checking out Browsersync's docs on integrating these technologies. That said, feel free to reach out if you have any questions or comments regarding this article and I will be sure to get back to you as soon as possible!