Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Minimalist-omakase build tool for node.js projects

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.


A minimalistic build tool for Node.js projects.


npm install -g bob


Install project dependencies (per Node.js project):

bob dep

Run Bob from project directory:

bob target1 target2 target3 ...

Run Bob with specific environment (by default it uses NODE_ENV=development):

NODE_ENV=production bob start

Run Bob in robot mode (generate XML reports):

BOB_MODE=robot bob style lint test

Project Convention

  • package.json - project descriptor
  • lib/ - .js library files
  • test/ - .js test files
  • build/ - reserved and generated by Bob to store buildtime reports/artifacts
  • run/ - reserved and generated by Bob to store runtime logs/pids
  • (optional, only relevant when your project is an app) {name}.js - main app file, must support node {name}.js start|stop|restart|status


  • clean - Delete build/ and run/ directories, along with any nohup.* and *.log files
  • style - Run jscheckstyle against all .js files under lib/ directory, configurable via {}
  • lint - Run jshint or nodelint against all .js files under lib/ and test/ directories, configurable via {bob.lint.files}
  • test - Run vows against all .js files under test/ directory, configurable via {bob.test.files}. Run npm test if scripts.test exists in package.json
  • coverage - Run vows against all .js files under test/ directory with coverage flag, configurable via {bob.coverage.files}
  • package - Create a .tar.gz package at build/artifact/ directory, along with md5 and sha1 checksums.
  • package-meta - Add a meta file to build/artifact, along with md5 and sha1 checksums.
  • versionup - Upgrade build version number in package.json
  • versionup-minor - Upgrade minor version number in package.json
  • versionup-major - Upgrade major version number in package.json
  • template - Replace variables in template files with values from package.json. E.g. bob.template config in Config example above, will replace ${version} and ${name} in conf/artifact-meta.json with '0.0.1' and 'myproject'
  • stop - Stop the app. Run npm stop if scripts.stop exists in package.json
  • start - Start the app. Run npm start if scripts.start exists in package.json
  • restart - Restart the app. Run npm restart if scripts.restart exists in package.json
  • status - Display app status
  • nuke - Kill all processes with command containing the word 'node'
  • send - Send the artifacts to {bob.deploy.user}@{}:{bob.deploy.port} at {bob.deploy.dir}, remember to configure the private key for the specified user
  • deploy - Send, then unpack the main .tar.gz artifact
  • deploy-r - Deploy the package and then remotely restart the app


Bob reads package.json file. NOTE:

  • each property under "bob" is optional
  • bob property value with ${name} or ${version} will be populated with name and version values accordingly


    "name": "myproject",
    "version": "0.0.1",
    "bob": {
        "src": {
            "dir": "mysrc/"
        "style": {
            "files": "foo.js bar/",
            "opts": "--checkstyle"
        "lint": {
            "files": "foo.js bar/",
            "opts": "--jslint-reporter --config path/to/hintconfig.js"
        "lintstrict": {
            "files": "foo.js bar/",
            "opts": "--reporter path/to/lintreporter.js --config path/to/lintconfig.js"
        "test": {
            "files": "bar/*.js",
            "opts": "--dot-matrix"
        "coverage": {
            "files": "bar/*.js",
            "opts": "--cover-html"
        "packagemeta": {
            "dir": "conf",
            "file": "artifact-meta.json"
        "template": {
            "conf/artifact-meta.json": ["version", "name"]
        "deploy": {
            "user": "myuser",
            "key": "/local/path/to/mykey"
            "host": "myremotehost",
            "port": 22,
            "dir": "/remote/path/to/${name}/${version}"


Follow @cliffano on Twitter.

Something went wrong with that request. Please try again.