Bower was created and released by Twitter in 2012, part of a open-source movement that the company undertakes. Like npm for Node.js and gem for Rails, Bower aims to be the package manager for the web.

Bower does well in solving certain aspect of package management such as fetching and installing package, checking of package dependencies and compatibility, etc. But those does not make up the complete chain of package management.

My ideal package manager can install and inject my required packages in the right order with the correct file path reference automatically.

To reach that state, I will need a help of a build tool. Ok, let's start with a simple use-case - Include jQuery and jquery.hammer.js in your website

The traditional package installation usually goes like this:

Go to the jQuery website Download the jQuery file (version 1.11.1) to the download directory Copy and paste the jQuery file to the working directory Manually reference the jQuery file in the correct order inside your working file (eg. index.html ) Next, to install jquery.hammer.js, repeat Step 1 - 4 You realise jquery-hammer depends on jQuery 2.0. Repeat Step 1 - 4 to install the correct jQuery version.

The Pain of Package Management

With the above flow for package installation, a developer used up a good part of his cognitive load before he starts developing:

Discovery of packages - Where to download the plugin? Checking of package dependencies - What other libraries I need to make my plugin work? Compatibility of packages - Will my package be affected by other packages? Ordering of package referencing - Which files should I include first? Manually finding the correct files within the package - Which file/s in these entire package is/are the right file to import into my project Manual reference to the individual file path which introduces potential typo error - Did I type the right file path?

These pain will scale in magnitude as the website gets more complicated and the amount of packages increase.

It's Bower Time

Let's use Bower to tackle the aforementioned problems.

With Bower globally installed:

Install jQuery: bower install jquery#1.11.1 Install jquery.hammer.js: bower install jquery-hammerjs

Bower prompts error and ask me to pick my preferred version. If 2.0 is selected, the jQuery library will be auto-updated. Manually reference the jquery.hammer.js file and its dependencies in the correct order inside the working file.

Bower downloads the libraries and dependencies straight into my working directory. It also checks for and resolves compatibility issues. But that's about it. Bower managed to solve problem (1) - (3), leaving problem (4) - (6) intact.

Build Tool takes the wheel!

Bower is an un-opinionated package manager. It allows free play on the integration of bower into your current workflow and tooling by providing the developers with a manifest file (bower.json), configuration file (.bowerrc) and hooks.

Let's take a look at bootstrap's bower.json:

We shall focus on two important options: main and dependencies .

The main option can take in a string or array. It declares the necessary files to use the package. The dependencies options declares the package dependencies.

The npm package that I had selected, grunt-wiredep , takes advantage of these configurations to wire up the dependencies and installation.

Grunt, I choose you!

I will be using Grunt but other build tools like Gulp or Broccoli are suitable too.

Setup

My working directory is simple. It just has a index.html in it. Follow the steps below to prepare your working directory for awesome package management. Make sure your npm, grunt and bower are installed.

At the root of the working directory, setup the package.json:

npm init Setup the bower.json:

bower init Install grunt-wiredep and matchdep npm package:

npm install --save grunt-wiredep && npm install --save matchdep Create a Gruntfile.js in your working directory Insert the placeholder in your index.html

Now that your directory is prepared, you are ready to install your packages.

Install jquery

bower install -S jquery-hammerjs grunt

With grunt-wiredep , the files are ordered automatically and inserted into the index.html with the correct file path reference. This effectively solve problem (4) - (6).

Let's try installing bootstrap.

Install bootstrap

bower install -S bootstrap grunt

You can check out the above example from my github repo, bower-grunt, and try installing a few other packages such as Backbone. You will find that package installation had become a trivial task.

We live in a imperfect world

For the build tool to work effectively, every package must have the main and dependencies stated accurately by the package owner. However in the real world, you will bound to come across packages that have missing or incorrect main and dependencies options. All is not lost though. You can override those missing options with grunt-wiredep , using the overrides option.

Look out, ZSH users!

Initially, I wasn't able to install specific package version by bower install <package>#<version> . I keep getting this error: no matches found .

After some googling, I found that my shell, ZSH, was the problem.

You can fix it with alias bower='noglob bower' .

Conclusion

Some of you might find that the overhead to insert a few lines of javascript files is too high. But keep in mind that you will only need to configure the setup once and package installation becomes very scalable.

I'm beginning to use Bower, combined with Grunt, for all small and large projects. The ability to grab libraries off the command line and immediately start development is an empowering feeling. Those days of manual fetching and installation packages seems long gone.

Slides: