Photo of wisteria Photo by Annie Spratt on Unsplash

Made In The Shade With Bower


The best laid plans…

It started out so simple. The thing you originally designed was just some simple HTML, a bit of CSS, and just enough jQuery to talk to your server back-end and update the DOM. What you ended up maintaining, however, has mutated into a sprawling giant with a "front-end framework" (Bootstrap or Foundation), dynamic CSS (like less or sass), jQuery and fifty-three plugins for it, some utility libraries (a la underscore), templating libraries (maybe mustache or handlebars), etc. ad nauseum.

"My back-end doesn’t look like this," you think. "It’s all nicely organized, and
easy to keep straight. But my front-end is a mess! Where did I go wrong?"

Silly rabbit, you didn’t use Bower.

Bower? What’s Bower?

Bower is a front end package manager built by the folks at Twitter for web sites and web applications. It helps you keep all those crazy bits you found all over the web and copied into your project straight.

Even better, like most package managers, it tracks dependencies between your umpteen components, so when it comes time to upgrade something in the middle of your giant jQuery plugin stack, you have at least a hope of figuring out what needs to go where.

Not another package manager!

I know what you’re thinking, and you’re right. Aren’t package managers usually pretty complex? Do I really have time to learn all the ins and outs of another package manager?

Well, in some cases (cough maven) package management systems can be a complete bear. But enhance your calm! Bower is about as simple as it gets.

OK, so how does it work?

Well, after you install bower (using npm…you have npm installed, right?), to install a package, you just run:

$ bower install \

If you want to specify a version, you can do this:

$ bower install \\

The version is a semver version, and should correspond to a tag in the github repo of the package you are installing, if at all possible.

If you want it saved to a list of installed packages for your project, add the --save flag::

$ bower install \ --save

More on that later…

What happens is this: Bower takes your package name, and looks it up in an online registry of bower packages. There’s a default public registry online, but you can set up your own private registry if you want.

Bower then gets a url from the registry, and uses that to download the package. This is usually a github or other git url, and Bower will pull down the package
using git, so you’ll need that installed.

Then bower puts the package in a directory called "components" (by default — the name is configurable) under your project directory. Easy Peasy.

But the packages are complicated, right?

Uh, no. A "package" in bower terms is just a bunch of arbitrary files, one of which is called "component.json". And before you say anything, no it’s not

It’s just a JSON file, and it looks like this:

  "name": "bestProjectEvar",
  "version": "1.2.3",
  "main": "./path/to/main.js",
  "dependencies": {
    "jquery": "~1.7.2"
  "devDependencies": {
    "qunit": "1.10.0"
  "ignore": [

Bower only cares about six things in the file, though I suppose you could clutter it up with other things if you wanted.

  • name: the name of the package
  • version: version of same
  • main: the name of the “main” file in the package, or an array of names if you specify more than one. This appears to be optional and doesn’t actually seem to do much as far as the behavior of bower is concerned.
  • dependencies: an object specifying dependencies of the package, with package names as keys, and semver_ versions as values
  • devDependencies: this is like dependencies, but for things you only need for development
  • ignore: stuff in your repo that you want bower *not* to install when it installs the package

Most of the packages I’ve looked at only use name, version, and dependencies.

Creating your own bower package is trivial. You just create a component.json file in the root of your project file structure. Bam! Done.

In fact, you can make your project directory that you just installed all those bower packages into a component. If you do, and you just run bower install (without specifying a package name or url), bower will pick up the component.js in the current directory and install all of it’s dependencies. And if you use the --save flag like we talked about above, bower will even insert whatever you installed into that file to use later.

Other Goodies

But wait, there’s more…

First of all, Bower has a few other handy commands that you might expect to find in anything calling itself a package manager:

  • bower list – shows a nicely-formatted tree view of all thepackages installed in your project directory.
  • bower search – searches the registry for packages matching a keyword
  • bower info – show available versions for a package
  • bower register – lets you register a package with the online registry
  • bower uninstall – I’ll let you guess what this does

Secondly, and possibly best of all, bower exposes all of it’s functionality through a JavaScript API, so it makes a dandy building block for integrating into more complex tools or project-specific tool-chains.

Finally, there’s even an experimental bower completion command, to generate a bash/zsh command completion script. How cool is that?

Final Thoughts

I don’t know about you, but I’ve been wishing for a tool like Bower for a long time (longer than I care to admit). It’s simple, but it’s simplicity makes it easy to build other tools on top of it, and integrate into existing workflows. Other front-end package managers I’ve looked at all seem to be trying to impose a specific workflow, rather than trying to accommodate mine.

If you’re looking for a tool to organize your front-end code without complicating your life, check out Bower. I think you’ll like it.

I know I did.

+ more

Accurate Timing

Accurate Timing

In many tasks we need to do something at given intervals of time. The most obvious ways may not give you the best results. Time? Meh. The most basic tasks that don't have what you might call CPU-scale time requirements can be handled with the usual language and...

read more