Automatically download & use FrontEnd JS dependencies with Bower + Grunt boilerplate free

posted in: Javascript | 6


Today I wanted to talk a little about Bower and Grunt.

Bower is a package manager for FrontEnd JS dependencies mostly. You create your bower.json (components.json before, now depracated), put all of your dependencies in that file, and then just run bower install. That will download all of those dependencies and copy them to components/ folder inside your project. However, this will download the WHOLE git tag, which has a lot of boilerplate you won’t need like README, build files, and so on. Bower tells you to link to the file in /components/angular/angular.js but I don’t really like that. I’d rather those dependencies are copied to my “output” folder or something like that but that’s not possible with Bower out of the box.

That’s where Grunt comes to play :). Grunt is a Javascript Task runner. It’s very similar to Rake. It lets you add tasks and execute them sequentially.

What I want to show you guys is how to just run grunt and it will download bower dependencies automatically and copy only the main file to some output folder you want, without all that components boilerplate. Pretty neat right?

So, what do you need to do

1) Install NODE + NPM. I recommend installing it with NVM but it’s just a matter of choice.

2) Install grunt to be used everywhere in your enviroment. That can be done running npm install grunt-cli -g

3) Install bower to be used everywhere in your enviroment. That can be done running npm install bower -g

4) After this, we have everything configured to start working. Grunt also supports adding some plugins to run some cool tasks. Those plugins will be downloaded for this specific case. For that, we can create a package.json and npm will then take care of installing all of this plugins when running npm install. So, create a package.json like this:

Take a special look into the devDependencies. In there, we’re stating that we need 2 bower plugins that we’ll use later.

5) Create your bower.json with the dependencies you need. You can either create one similar to the next one or running bower init to follow some guide to create it:

6) Now, we have everything we need to start creating our Gruntfile.js. This file is the one read when running grunt in that directory. Check this Gruntfile. I’ll explain it below :)

So, let’s explain this step by step. With loadNpmTasks we’re loading some plugin. As that plugin has been installed with npm install, it’ll be available through an npm task. As you can see, we import the 2 devDependencies we added in the package.json. The problem is that both of those dependencies actually define a task named bower, so by default I can’t import both as one would override the other. That’s why I first import one, then rename that one, and then I import the other. grunt-bower-task will take care of running bower install. grunt-bower will take care of retrieving the main file of each dependency and copy it somewhere.

As you can see above this loadNpmTasks, we call an initConfig method. In there we configure the tasks. First, we create a dirs object with a dest property that points to “dist”. That’s actually our output folder. We can change that to whatever we want. Then, we configure the bower task with the dev action. In there, we configure where to put the main dependency file that’s retrieved from components folder. There, we use the dirs.dest variable we configured and we put them in a “dependencies” folder inside there.

Then, I just configure that running grunt by default will call the build task, which first installs all dependencies and then copies them to where they’re needed.

That’s it! This is all we need to configure.

Now, you can just run:

npm install


And now you have all of your dependencies copied to /dist/dependencies. :) Just 2 commands after the configuration has been done.

I actually use this approach in Restangular, so you can check it out there.

I hope this helps you and that you can use this :)

Share!Share on FacebookTweet about this on TwitterShare on RedditShare on Google+Share on LinkedInBuffer this pageEmail this to someoneFlattr the author
  • Thomas

    If I am using Bower to grab Bootstrap but overriding a few of its files, how would I set this up so that I’m not copying Bootstrap’s files from the original Bower install over my adjusted files? If I move them into two different directories and then compile both over each other I’ll end up duplicating CSS or JS.

  • Nick Van Weerdenburg

    Shouldn’t the package.json dependency be grunt (which is supposed to be installed locally), and not grunt-cli (which is installed globally)?

    • Martin Gontovnikas


      Installing grunt-cli in package.json doesn’t install it locally anway. grunt-cli package depends on grunt, so it’s installed once we add grunt-cli to package.json.

      Also, in case you don’t want to install the grunt-cli (The command line interface) globally, adding it as a dev dependency in the package.json gives you the ability to call the grunt client from your console locally anyway, though not supported. Check

      So I think doing it this way, actually has the advantage of having one more step of “configurability” if anybody in the team actually wants this.

      Do you agree?

      • Nick Van Weerdenburg

        Hi Martin,

        As far as I can tell grunt-cli doesn’t list grunt as an explicit dependency so grunt still needs to be listed in package.json.

        I’m guessing this is since grunt-cli is meant to be installed globally and grunt locally.

        Thanks for the great post- it was very helpful to me.


        • Martin Gontovnikas


          You’re actually right. It’s getting grunt dependency because of transitive dependencies on the rest of the contrib packages.

          I’ll add this to the package.json as well :)

          Thanks for the input!

  • finestglasses j.

    On the online retailers casually pharmaceutical drug eye glasses, you’ll receive these kinds of Designer Glasses in technique affordable prices than these for the physical retail stores.