Working for a company like GE, there are a lot of rules that restrict the sharing of internally developed tools.  For the most part, anything that we build on the company’s dime has to stay within the company.  Not necessarily a bad thing, just the way it is.  However, it does restrict the amount of sharing that we can do.  If someone in Oil & Gas builds a component that I might want to use on a Power project, I’d have to already know it exists, or run a search in our massive corporate GitHub.  Obviously this is not ideal.

As an effort to try to remedy this, I did some digging to see how we could implement a private Bower library of our own.  It wasn’t hard to find resources – even the Bower docs mention spinning up your own registry.


To start, I had these resources that helped me get a better understanding of how Bower works:

None of these really accomplished everything that I was looking for, but they all gave me a good starting point, and helped me learn a bit about how Bower works.  I highly suggest you look at their projects as well.

As for my project, you can find all of the code on my GitHub.


The Bower registry is nothing more than a database that stores a name, a URL, and some metadata about a package that lives in a publicly accessible repository (generally GitHub).  When you run the bower install [package] command, Bower makes a call to a registry to match the [package] to a corresponding record in the database.  At the very least, database entries have the following information:

    name: packageName
    url: packageUrl

Hence the fact that when you register a package, the command is bower register [package] [url].

Once the URL is returned to the client – that is, your machine – Bower continues the operation with a curl request to the URL.  The bower.json dictates information about how the package will be downloaded: what files to ignore, what to name the destination directory, and what other dependencies to fetch, just to name a few.  The big takeaway – building a private bower is as simple as building an API with a database that takes, at the very least, a name and URL as request data.

Getting Started

I only gave myself a weekend to build this, so I wanted to start with something that would make handling requests super easy.  Thus, I went with Express.

If you’re not familiar, Express is officially considered a middleware, good for handling client requests and passing subsequent requests off to a database, or to distributed web services.

I won’t get into the full details of what I took out that wasn’t needed.  What I will highlight is the super-small configuration necessary for passing new routes to an Express-based server.  Setting up Express will be covered in a later post, but for now you can read the documentation on how to get started.  I recommend using the Express Generator as a quick way to get up and running.

Adding a resource route

By default, no matter what the registry, Bower sends its requests to the /packages/ path.  That being said, we need to add a set of routes that will handle those requests.  So in the routes folder, we’ll add a packages.js file.

Now we’ll want to tell our Express app to associate that file with any incoming requests to the /packages/ path.  So at the top, where all of the application dependencies are declared add:

packageRoutes = require('./routes/packages')

Further down, just above where you see the comment regarding handling 404 errors, you can tie the request path to the appropriate file with:

app.use('/packages/', packageRoutes);

From here on out, any route-handling that we define will live in packages.js. But before we can do that, we also have to setup a database connection.

Adding the data resource

I went with MongoDB for this project, since I wasn’t sure how I would grow the data model and didn’t want to have to deal with continually migrating as I did.  Feel free to use whatever database you want, but the rest of this section will talk about how to set up Mongo to store our data.

In the vein of keeping concerns separate, create a new file in a new directory: model/db.js.  That will house your database connection.  Since I had Mongo installed locally, I ran npm install mongoose --save to include the Node connector, and then filled db.js with the following:

    mongoose = require('mongoose');

If you don’t have it already, install Mongo, and start your DB server by typing mongod in the command line.  In a separate command line window, type mongo to access your DB server’s console.  You’ll only need to type use privatebower, and then you can Ctrl+C out of there.  That command will create a Collection in Mongo that we’ll populate with our private Bower packages.

Next we’ll create another file in the same folder, called packages.js.  It’s in here that we’ll define the data model:

    mongoose = require('mongoose'),
    packagesSchema = new mongoose.Schema({
        name: {type: String, index: true, unique: true},
        url: {type: String, unique: true}

mongoose.model('Packages', packagesSchema);

Finally, we’ll add both of those to our app.js file, above where we include our routes:

    db = require('./model/db'),
    packages = require('./model/packages');

Handling Requests

Next we’ll look at how to handle the two basic requests any Bower registry will need: get and post.  My code goes a little further than this and builds out some metadata to add to the various packages, so what’s shown below won’t look exactly like it does if you’re following along with the project on my GitHub.  Instead we’re just going to cover the basics here.

Setting dependencies

Since we’ll be relying on a bunch of Node packages to facilitate handling data, we’ll need to pull those in at the top:

    express = require('express'),
    router = express.Router(),
    mongoose = require('mongoose'), //mongo connection
    bodyParser = require('body-parser'), //parses information from POST
    methodOverride = require('method-override'); //used to manipulate POST

We’re also parsing application/json data, so we want to communicate that to our Express application:

    .use(bodyParser.urlencoded({ extended: true }));

Posting a package

From here on out, we’ll be operating exclusively in routes/packages.js, and building on top of what’s listed above.  Everything can be added to that file in the order that it appears here.

We’ll define our POST route to the /packages/ path:

router.post('/', (req, res) => {
      name: req.body.name,
      url: req.body.url
   }, (err, pckg) => {
      if (err) {
      } else {

Not too much going on here, but we’ll take it line-by-line.  First, we receive a POST request to the root of this path that we’re defining, which is the /packages/ path.  Next, we pass in two properties to our callback, a request object, and a response object.  Those are standard to the Node server.

In our callback, we’ll first create a new record entry following the ‘Packages’ schema we previously defined in our model. We’ll populate the name and URL fields with data received from the request.  Remember, when you register a Bower package, that’s all you ever send.  Anything else has to be retrieved and entered programmatically.

We then supply a callback to the data entry method, which will handle any errors that may have occurred with a 421 status, and an error response to the client, or send a success status of 201 with the new package.

Getting a package by name

Bower retrieves package information from its registries by calling a GET request to /packages/:name, where :name is a route parameter used to find a record in the database.  You may have noticed that we added an index to the name property of our data model, and this is why.  Since Bower is DB agnostic, you can’t rely on a predictable ID strategy to find records (and no one would use it anyway).

router.get('/:name', (req, res) => {
        .findOne({name: req.body.name}, (err, pckg) => {
            if (err) {
            } else {

Simple enough, right?  Here, we’re sending whatever came across in our route parameter to the database, and asking it to find a record that has that string set as the name field.  Since Bower expects a name and URL to be sent back, that’s exactly what we’re going to send.  Remember, once you send back a URL, Bower will know what to do with it.

Configuring Bower

Bower won’t just know to look int your new private registry, so we have to configure it to look at a specific URL.  In this case, since we’re still in development, it’ll be on your local machine.  In the future, it might be at whatever domain you corporate DNS sets up for you, e.g. http://some.long.sub.domain.ge.com, as it is at my office.

Bower commands look up the directory tree of your machine for a file called .bowerrc.  That file indicates to the Bower command what behaviors it should adopt when running.  Since it’s a dot-file, it will be hidden on your machine if you don’t have hidden files shown.  For now, put this in an empty directory as we’ll use it to demo how to the private Bower works.  However you can always put this in a project root, or your machine user’s home folder as well, and it’ll be applied globally for that user.

The .bowerrc accepts a list pf properties passed as JSON, and you can find more information in the Bower docs.  For now, we’ll look at only a small set of those properties.  In your .bowerrc, add the following JSON:

   "registry": {
      "search": [
       "register": "http://localhost:3000"

This will set the two fields in the registry property to look to your local registry when making calls for packages; in the case of the search field, it will fall back to the main public Bower registry if it doesn’t find what it’s looking for in your registry.  You can add as many registries as you like, and Bower will search them in order.  For example:

  1. Your dev team’s private registry for business or project specific packages
  2. Your corporate division’s private registry for branded or role-specific packages
  3. Your corporate private registry for everything under the corporate banner
  4. The main public Bower registry

Registering a Package

Finally, we can move ahead with creating our first package on our private Bower.  In the command line, in the same directory where you add the .bowerrc file, run bower init, and answer all of the questions you’re asked.  Then add however many files you’d like for the purposes of this demo.

Start your private registry by running npm start in the command line at the root of your Express Bower application.  That will start a Node server to listen for requests on the routes you’ve defined for localhost:3000.

Next, commit all your new files, and push the project up to an empty GitHub repository.  Once that’s done, you’ll have the GitHub URL you’ll need to register your package.  Now finally you can run:

bower register your-package-name git://github.com/yourspace/your-package.git

You should be prompted with a question asking whether or not you’d like to register at localhost:3000.  Obviously you’ll be saying yes.  Once you respond, your package will be registered!  You can always dive into the Mongo console, or find a DB visualizer to help you keep track of what’s in your database.

Last, we’ll install it as well.  For the sake of this demo, you can do this in the same directory that you just registered, as Bower will create a bower_components/ folder for all installed packages.  You won’t have to worry about overwriting anything.  So, as a last step in this demo, run the following:

bower install your-package-name

You should see a newly created bower_components/ folder, and inside should be a folder with all of the files in your demo package!

Comments are closed.