Vawks Clamantis

Screaming at the top of my fingers.

A First Look at Bower

In September, Twitter released Bower, a “package manager for the web”. What does this mean? How is this different from projects like Volo, Ender, and Grunt? Let’s take a look…

A Tiny Little Helper

Bower is small. Very small. The largest file in the repo is only 394 lines and most of the other files clock in around 100, and most importantly, it has a very small feature set.

The only thing Bower does is copy sets of files into the ./components directory.

Oh sure, it will tell you which sets of files it has copied into ./components, or make it easier for you to copy new sets of files into ./components in the future, but Bower is a one-trick pony. This is a good thing.

Bower is easy to understand, so it’s easy for newcomers to pick up, but this doesn’t mean that it’s a toy. The bower ls --map command provides JSON that can be consumed by higher level tools like Yeoman, making Bower a very UNIXy tool in the modern web developers kit.

Is it like X?

Grunt? Nope. Grunt is a task-based command line tool. It comes with a lot of pre-defined tasks to help you do things like create a bunch of boilerplate code to start a new project, or run JSHint against all your files, or concatenate and minify all your CSS and JS files. Bower doesn’t do any of those things, and Grunt doesn’t want to download arbitrary packages.

Ender? Nope. Ender is a full-featured package manager. Not only does it install packages from the web, it also concatenates and minifies them into a single deployable file. If you want to include a local directory, it still needs a package.json file. To publish a package, you publish to npm. None of this is too hard, but as we’ll see, it’s about twice as complicated as Bower.

Volo? Nope. Volo is both a task tool and a package manager. It heavily favors AMD modules (no surprise, since it’s written by the creator of RequireJS).

Bower is a minimalist tool that helps you gather files.

Using Bower

Command Overview

Running bower help shows all the available commands. They fall into four categories:

Get Info on Local Packages

list, ls - these are actually just two ways to write the same command. typing either one will show you your current dependency tree

Change Local Packages

install - install new packages into ./components

uninstall - remove installed packages from ./components

update - updating the currently installed packages if new versions are available

Get Info on Remote Packages

lookup, info - report information on packages that have been registered with Bower

search - search the global Bower registry

Change Remote Packages

register - create a new entry in the Bower registry that will be visible to anyone in the world

Simple Bower

Let’s imagine that you keep a bunch of useful JS helpers in the folder ~/dev/my_library. If you were inside ~/footest and ran bower install ~/dev/my_library, Bower will create a new directory called ~/footest/components and copy /my_library inside of it.

You probably won’t use Bower to do local filesystem copies like this very often, but it shows exactly what is going on when you run bower install. The argument you pass will get copied into ./components relative to wherever the command is run, creating that subdirectory if necessary.

You can also pass the install command a http:// or git:// URL instead of a filepath, and Bower will download the file or repo from the URL. However you’ll usually be installing packages that have been registered with the global Bower system. Run bower search to see all the packages that people have registered, and then run bower install jquery.

This will create a ~/footest/components/jquery directory and populate it with a jquery.js file. WIN! (Make sure you’re in the root of your project when you run bower install, because it will create the components directory wherever you run it!)

Bower will also download a component.json file into /jquery. This describes the jQuery package. If jQuery declared any dependencies in component.json, Bower would dutifully go off, download them, and put them in ~/footest/components as well.

Notice that in our earlier example when we did bower install ~/dev/my_library, there was no mention of a components.json file. That’s because Bower doesn’t require one. It’s very happy to just copy over a folder of files. If you have a components.json in that folder, that’s just a bonus.

So, Bower gives you an incredibly easy way to install packages. Now what? How are you supposed to get them into your web app? Well… The truth is that Bower doesn’t care. You can just use <script> tags if you want, or you can use a build system like Grunt, Yeoman or the RequireJS optimizer to concatenate your files.

Writing Your Own component.json

You can get even more functionality out of Bower by creating a file called component.json in the root of your project. Here is a sample from the Bower website:

1
2
3
4
5
6
7
8
{
  "name": "myProject",
  "version": "1.0.0",
  "main": ["./path/to/app.css", "./path/to/app.js", "./path/to/sprite.img"],
  "dependencies": {
    "jquery": "~1.7.2"
  }
}

The name and version keys are self explanatory.

The main key declares the files that the package “exports”, and is used by bower ls --map and bower ls --path. (Theoretically, if you are never going to publish your package, and never using a build system that relies on these Bower commands, you could leave main undefined, but I recommend defining it.)

Dependencies are where the real savings come in. When you run bower install in the root directory of your project, all the dependencies you declared in your component.json get installed …and their dependencies …and their dependencies.

Better still, you can lock down which version gets downloaded. Dependencies can be declared as a strict version number such as 1.4.2 or can use comparison operators like >=.

The ~ operator is extremely useful, because it will look for the latest version after the one specified (like >= would), but ~ will only bump the least significant part of the version specified. So specifying ~1.4.1 would look for the highest 1.4.x release. Additional examples can be found in the documentation for ranges in semantic versioning.

If you already have a component.json file in your project, and you decide that you need to add components, you can save a little time by using the --save flag with bower install. This will add an entry for the new component into the dependencies hash inside your project’s components.json. It only currently works with registered packages, not packages installed via URLs or filepaths.

Publishing Your Component

You, too can create a component that shows up when someone types bower search. All you have to do is publish your package on GitHub. Then run the bower register command passing an unregistered name, and the repo’s GitHub URL. Voila!

If you include a component.json file at the top level of your repo, Bower will install your package’s dependencies for anyone who installs your package. If you don’t include a component.json, Bower will generate one when it installs the package.

Names are first come first serve, so get ‘em while they’re hot!

In Conclusion

I like simple tools. I like Bower.

What’s in a Name

A bower is a house that a bowerbird creates by gathering objects from all over the forest.