Using Browser-Sync with Yeoman Webapp


This post is super old. Just go to instead.

Anyone with a multi-device testing suite will know the pain of testing forms or simply navigating through a site one browser at a time. Enter grunt-browser-sync, a GruntJS task that handles things like:

  • Links: Clicking a link will update all browsers with the new URL
  • Scrolling: Scroll in one browser or device and watch as the rest follow your command
  • Forms: Enter text in to one form and, yup, all other device browsers follow suit!

Hooking it up

Here's how to get Browser Sync up and running with Yeoman's webapp generator. I assume you know how to get the basic webapp up and running, so I'll skip that part. If not, follow the awesome documentation at

First, let's install grunt-browser-sync:

$ npm install grunt-browser-sync --save-dev

Edit Gruntfile.js

Next we'll edit the Gruntfile.js that came with webapp. There are only two edits required to make this happen. The first is to add the browser_sync task options:

browser_sync: {
    files: {
        src : [
    options: {
        watchTask: true,
        ghostMode: {
            scroll: true,
            links: true,
            forms: true
        server: {
            baseDir: ''

This config is setup to watch all files that may change in the app, which is just a copy-paste from the livereload section. We've also set the 'watchTask' option to true in order for Browser Sync to work with the grunt-watch task, enabled ghost mode for scrolling, linking, etc, and have set the root directory to our app directory. Check the Browser Sync README for more options.

Add the Task

The last step is to add the task itself. The documentation instructs to place the browser_sync task before the watch task:

grunt.registerTask('serve', function (target) {
    if (target === 'dist') {
        return['build', 'connect:dist:keepalive']);

First Boot

You should be able to fire up grunt server from here. Point all your devices to the URL Browser Sync has automagically figured out is your local URL and watch as pure magic happens right before your eyes.

View the full Gruntfile.js


One thing I found out about the form sync feature is each field needs to have an ID attribute. Of course you have that already for all your accessible form labels, right?

Back to blog