Observe your web design changes in real time with BrowserSync

Amazon AD Banner

If you're a web designer or developer, you have probably faced the situation where you're creating a website or application for the browser, making it responsive and cross-browser compatible (which means it works on almost every browser available, including IE) and every time a change is made to the HTML, CSS or JavaScript files you're working on, you have to hit the refresh button on every browser and device (phones, tablets, smart TVs, e-readers, you name 'em!) to see the new changes being reflected.

Bsync

Also, if you're serious about cross-browser compatibility and responsive design your physical setup might look like this: a dozen of mobile phones of different sizes, companies, and approaches; tablets, convertibles, 2-in-1s, more than two monitors and probably even some Kindle e-readers here and there (I know, I'm exaggerating). Wouldn't it be nice if, when you do a scroll or a click, all your browsers do the same? Imagine how cool, this is true cross-browser testing, you can see your file changes and UI interactions in real time!

What do I need?

NodeJS and NPM (comes with NodeJS), NodeJS is a JavaScript runtime environment, Chrome's V8 JavaScript engine running on your machine or server, and NPM is the Node Package Manager that you can use to install some of the millions of community packages out there, developed by the NodeJS community.

If you don't have NodeJS installed in your computer, you can check by typing node in your command line and if you do have it, a prompt will be shown where you can type JavaScript as if it were your browser's developer console. If you don't, it will say that the command isn't recognized and you'll need to head up to the official NodeJS website to install it (along with NPM).

Start with the command line

We can use BrowserSync both as a command line tool and during the build process with tools like Gulp or Grunt, as a matter of fact, I'm gonna teach you how to use it directly from the terminal and Gulp. If you're not familiar with any of these tools or the command line, I suggest you start learning about 'em, they're very important when developing software and websites or apps.

The first thing you have to do is open up the terminal (Mac and Linux, for Windows press Win+R and then type in cmd and then hit ENTER) and type the following command:

npm install -g browser-sync  

Note: If you're on Mac or Linux and it doesn't work, it may be a permissions issue, it can be solved by adding sudo before npm, it will ask you for your root password. So, the command would have to be typed as sudo NPM install -g browser-sync.

We're telling NPM to install the package called browser-sync on our computer, but with the -g flag, we're also telling it to install it globally, this means that you can execute the browser-sync command in every directory.

If everything went well during the installation, you will now be able to type the browser-sync --version command in your terminal and it will spit out a version number.

Setting everything up

You need a directory to work on, for example, if you're working on a client's website located at /home/Documents/client-website (or C:/Client Website), you need to start your server/proxy in this directory. If you don't currently have a project to test BrowserSync, let's create one:

Example Location: C:/users/Luis/Documents/ClientWebsite/

/ root path
-> index.html
-> style.css
-> script.js

Now it's time to fill them with some boilerplate code:

index.html:

<!DOCTYPE html>  
<html lang="en">  
<head>  
  <meta charset="UTF-8">
  <title>Testing BrowserSync</title>
  <link rel="stylesheet" href="style.css">
</head>  
<body>  
  <h1>Hello world</h1>
  <p id="render">I'm testing BrowserSync and what it can do.</p>
  <button id="btn">Fill Paragraph</button>

  <script type="text/javascript" src="script.js"></script>
</body>  
</html>  

style.css:

body {  
  background: tomato;
  color: white;
  font-family: Arial, sans-serif;
}

script.js:

function repeat(str, num) {  
  return (num > 1)? str + repeat(str, num-1) : '';
}

var paragraph = document.getElementById('render');  
var button    = document.getElementById('btn');  
var phrase    = "I'm testing BrowserSync and what it can do.";

button.addEventListener('click', function(e) {  
  paragraph.textContent = repeat(phrase, 400);
});

The aforementioned files are the ones you need to have in your directory to start working on the project, BrowserSync injects javascript code to your HTML files so, they need to have a body tag (if you're on a NodeJS workflow with a templating engine, your layout can have it) and that's a must.

Starting the server

The hour of truth has come, all you have to do is navigate to your project's directory (using cd) path with the command line and once you're there, type in the following command, I will explain it with detail:

browser-sync start --server --files "*.css, *html, *.js"  

What we're doing here is start the browser-sync watcher, which will start a server (the IP for us to visit is given to us by the tool) in the port 3000 by default, pointing to localhost. You can use that IP to connect to it with any device that's connected to your internet (must be connected to the same network).

And we also tell what files to watch for changes from now on by using the --files flag, there are more options available at the official BrowserSync Documentation but we'll stick with the basics. This is the output that I get when doing the above:

[BS] Access URLs:
----------------------------
Local: http://localhost:3000  
External: http://192.168.0.2:3000  
----------------------------
UI: http://localhost:3001  
UI External: http://192.168.0.2:3001  
----------------------------
[BS] Serving files from: ./
[BS] Watching files...

The first useful data that we get from the output is that we can visit http://localhost:3000 to see the project on my computer, that's cool, but if you also want to see it from other devices you may want to visit the External IP address along with the port, don't forget about the port 3000.

The UI part is just the BrowserSync panel where you can set multiple settings, it's definitely worth checking out! And finally, let's talk about the --files value, what are those odd asterisks you see? Easy, that's a pattern that BrowserSync will follow to know which files to watch for.

In here, the asterisk represents "any", if you put the asterisk before the file extension (--files "*.js"), it's telling the tool to watch for any file name with a certain extension; if you put an asterisk before and after the dot (for the extension) like --files "*.*" it will watch any file name with any extension. You can use directories here, for example --files"/css/*.css" as the Documentation says or even use a double asterisk in between forward slashes to represent "any subdirectory", an example would be --files "/assets/**/*.*" (any file with any extension in any subdirectory, including the current one) and finally, you can separate multiple patterns by a comma as in the first example.

Using BrowserSync, the fun part

Once you initialize the server, a new tab will be opened in your browser, the index.html contents will be displayed there, or you can visit the provided IP address with the corresponding port (3000 by default). Now try changing any of the files in the project directory, if you modify index.html or script.js, you'll notice how it automatically reloads the browser for you to see the new changes, if you edit the CSS, then you'll see the styles injected mostly without reloading the page. You're free to play with it; try using different devices at the same time, interact with the button I gave you (it inflates the paragraph) and scroll to see how all devices scroll with it.

Gulp + BrowserSync

You may be interested in using it along with a great build tool like Gulp, why? Because it allows you to set everything up once and then run Gulp, let it worry about what files to watch and when to reload, configure it with ease and also reload when a change to the backend code is made (if you're a Node developer, you may wanna check out Nodemon). You can build great boilerplates with Gulp and use it in every frontend or full-stack project you can possibly imagine, it will save you a lot of time.

I use Gulp with BrowserSync because I want my browser to reload when I make changes to SASS files, or transpile ES6 code with Babel, minify my scripts and styles or do some changes to my app's codebase (the backend code, let it be Ruby, Node, Python or whatever you love and care about).

The first thing you have to do is make sure Gulp is installed both locally (you will do it with the command below) and globally on your computer/server, create your Gulpfile and then install the browser-sync plugin for Gulp.

npm install browser-sync gulp --save-dev  

If you already have gulp in your package.json file, remove gulp from the command and just leave browser-sync.

Now, in your gulpfile.js file, require the module and set up the task for initializing the server.

var gulp = require('gulp');  
var sync = require('browser-sync').create();

gulp.task('browser-sync', function() {  
  sync.init({
    server: { baseDir: "./" }
  });
});

Now, you need to tell it which files to watch for with gulp.watch(). For example, to watch for changes in any HTML file within your project, you can add the following piece of code after sync.init(...) inside your browser-sync task or a default/serve task:

gulp.watch("/**/*.html").on('change', sync.reload);  

But what if you're using transpilers and template engines, let's say, you have a Jade+SASS workflow. You may need to consider piping the end result of the transpiling through sync.stream(). Here's a basic example to watch for SASS changes and reload the browser when the transpilation is done:

var gulp = require('gulp');  
var sync = require('browser-sync').create();  
// You need to install the package first
// with "npm install --save gulp-sass"
var sass = require('gulp-sass');

gulp.task('sass', function() {  
  return gulp.src("/sass/*.sass")
    .pipe(sass())
    .pipe(gulp.dest("/css"))
    .pipe(sync.stream());
});

gulp.task('default', function() {  
  sync.init({ server: "./" });

  gulp.watch("/sass/*.sass", ['sass']);
});

What this code is going to do is, when a .sass file inside the /sass/ directory changes, it will invoke the sass task and the task will, in turn, get every SASS file inside, transpile them to plain old CSS and insert them as .css files inside the /css directory (all of this can be changed to suit your own needs), and in the end, inject the new styles to the browser.

Conclusion

BrowserSync can be invoked with Gulp or Grunt with different types of tasks and changes, there are multiple plugins you can use with those tools and reload the browser after those plugins have done their own thing. There's a similar tool called LiveReload, it has a nice browser extension and integration with various text editors.

These comments are powered by Disqus