Ex Machina's frontend build tool

#nBob Ex Machina's second generation frontend build tool, based on Node and V8, focussing on:

  • Ease of use
    • Includes local build server
    • Shows build errors directly in browser
  • Performance
    • Incremental builds
    • Multi-core processing
  • Predictability
    • Single mode (no development vs production)
    • Build on browser reload
  • Conciseness
    • Minimal project configuration
    • Efficient processor plugin API

See the releases page for a changelog.

Licensed under MIT License and Copyright Ex Machina.

Start by installing Node if you don't have that yet.

Then install nBob through NPM; open a terminal or command prompt and type the following on your command line:

On OS X and Linux:

$ sudo npm install -g nbob

On Windows:

> npm install -g nbob

If an update is available then nBob will notify you and you can update similarly:

$ sudo npm update -g nbob


Running nbob in your terminal with invalid or incomplete arguments will result in it's help being displayed:

nBob v<version>

Usage: nbob [options] <commands>

    nbob        Create nbob-config.json
    skeleton    Copy skeleton files
    browsers    Create browserslist file
    aws         Create ~/.aws/credentials
    api         Update EM api directory
    doc         *Update doc directory
    l10n        Update l10n directory
    lib         *Update lib directory
    endings     Convert text file line endings
  clean         Remove build and dist directories
      png       Compress PNG images
      l10n      Localize texts
      minify    Minify HTML
      templates Concatenate templates
      hbs       Compile Handlebars templates
      less      Compile LESS to CSS
      post      Post process CSS
      style     Analyze and Fix JS with JSCS
      hint      Analyze JS with JSHint
      esnext    Transpile ES6+ to ES5 with Babel
      minify    Minify JS
      concat    Concatenate JS files
      amd       Optimize EM AMD modules
      test      *Run tests
    include     Include files
    substitute  Substitute in file paths and text
    dist        Write files to dist directory
  server        Make and host files
  deploy        Make and copy to S3

  -d, --dir     Use specified working directory (default: <current working directory>)
  -e, --env     Use specified environment config overrides
  -l, --level   Use specified log level (spam/debug/info/ok/warn/error/silent) (default: info)
  -o, --option  Override specified option in config (e.g: -o server.port=8081)
  -r, --reload  *Run live-reload server on dist directory
  -s, --sync    *Run browser-sync server on dist directory

*) Not yet implemented

Note: Like options, commands can be abbreviated, per example:
Full length:    nbob --env=staging update:api deploy
Abbreviated:    nbob -e staging u:a d


Configuration consists of nBob package defaults (nbob-config.json) which can be extended and overridden by user defaults (~/.nbob/nbob-config.json) and finally project configuration (<project>/nbob-config.json).

These configuration files are JSON files with section keys, aside from a few special ones (nbob, project and envConfigMap), referring to the command that they define.

The active configuration can be further influenced by specifying options (--env and --option) on your command line.

Most configuration sections include a files key that specifies an array of glob patterns for files to be included and excluded (by starting glob string with an exclamation mark !). For glob syntax details, please see the documentation of the used matcher: minimatch.

Most, if not all, files configurations will be pre-configured to match the appropriate files by convention, but in some cases you will have to manually opt-in to using a command processor by adding files globs in your project configuration.


When one config object is extended by another then any new properties are added and any existing properties are overridden.

When one config array is extended by another then all items from the other array are added to the first. However, when the extending array starts with the special item !! then the original array is first emptied, effectively replacing the array.


Configuration values can contain substitution syntax, inspired by Mustache templating.


    "make:js:concat": {
        "files": [ "{lib,src}/**/*.min.js{,.map}" ],
        "output": "{{project.name}}-{{project.version}}.min.js"
    "make:js:amd": {
        "files": [ "{{make:js:concat.output}}{,.map}" ],
        "exports": []

Results in project name and version being filled in to generate the JS concat output filename and the AMD using that output filename as input.

Note: Substitution by non-string config object values is currently also supported using Mustache partial sytax, p.e: "files": "{{> update:l10n.files}}". It is however a deprecated feature since it does not combine well with config extension and will be removed in the future.


The special configuration section with key nbob has the following options:

  • multiCore = true - Toggles multi-core processing on or off
  • host = 'localhost' -
  • openbrowser = false - If set to true will open browser window when starting $ nbob server


    "nbob": {
        "multiCore": false,
        "host": "localhost",
        "openbrowser": true

Adding this section to your user config file (~/.nbob/nbob-config.json) would result in all of your builds defaulting to not using multi-core processing. This can be useful if you have found that the overhead does not outweigh the improved processing speed on your system.


The special configuration section with key project has the following options:

  • name = "Unnamed" - Used to name build artifacts, you should define this in your project config file
  • version = "0" - Used to name build artifacts, you should define this in your project config file
  • files - Can be used to exclude (or un-exclude) certain files or directories
  • buildDir = "build" - Name of project subdirectory where to write build artifacts
  • distDir = "dist" - Name of project subdirectory where to write distribution artifacts


    "project": {
        "name": "awesomo",
        "version": "1.2.3",
        "files": [ "!!nbob-config.json", "!res/unused-theme/**/*" ]

Results in nbob-config.json being un-excluded and the unused-theme files being excluded from all processing.


The special configuration section with key envConfigMap can be used to specify a number of named environment configs. When you specify the name of such an environment using the --env option your config will be extended with that environment config.


    "make:substitute:path": {
        "substitutes": {
            "SERVER": "dev-backend.playtotv.com"
    "deploy": {
        "bucketName": "dev.playtotv.com"
    "envConfigMap": {
        "staging": {
            "make:substitute:path": {
                "substitutes": {
                    "SERVER": "staging-backend.playtotv.com"
            "deploy": {
                "bucketName": "staging.playtotv.com"

Will result with $ nbob d deploying to dev.playtotv.com and $ nbob -e staging d deploying to staging.playtotv.com. It will simultaneously substitute __SERVER__ by dev-backend.playtotv.com or staging-backend.playtotv.com in their respective environment artifacts.


If you want to quickly override a single configuration value you can use the --option command line option.


  • $ nbob -o server.port=8081 s - In case you want to run multiple nbob servers
  • $ nbob -o deploy.force=true d - In case you want to force a deploy of all files (not just the changed ones)


Commands combine a processor with configuration to provide a specific type of functionality. Their names are hierarchical, separated by colon characters :. When you execute a command you will also execute all of it's subcommands. If a Command specifies any dependencies, those commands will also be executed. Commands and subcommands are executed in the order that they were defined (though still processed parallelly where possible). When referenced from the command line, command names can be abbreviated.


    "make:js:concat": {
        "description": "Concatenate JS files",
        "processor": "concat",
        "files": [ "{lib,src}/**/*.min.js{,.map}" ],
        "output": "{{project.name}}-{{project.version}}.min.js"

Uses the generic concat processor to concatenate JavaScript files and their source maps.

Note: Through config extension not only command configs, but also their processor references can be customized. You can even add extra commands this way! Support for using your own custom processors will also be added in the near future.


TODO: Add support for showing processor help (e.g: nbob -h make:js:minify) and copy output here

For now, please see processor source files for more information on how they work and package.json for links to used third party dependencies.


Here are some links to third party tools that might be used for pending processor implementations:


nBob uses the following filename and directory conventions:

  • inc/**/* - HTML include files
  • l10n/*.json - Localization dictionary files
  • lib/**/*.js (and optionally *.map) - External JavaScript files from other projects etc. to be included into this project
  • src/**/*.js - This project's JavaScript files
  • templates/**/*.html - HTML template files to be compiled into directory JSON files
  • templates/**/*.hbs - Handlebars template files to be compiled to JS files and later
  • **/*.{html,css,js,json,less,png} - Respectively HTML/CSS/JS/JSON/LESS/PNG files (e.g: use extensions)
  • **/*.min.* - Minified files (e.g: foo.min.js from foo.js)
  • **/*.map - Source map files (e.g: foo.min.js.map for foo.min.js)
  • **/*-l10n{,-*}.{html,hbs} and **/*-l10n/**/*.{html,hbs} - Files to be localized
  • __BUILD__/**/* - Files to be prefixed with build digest (e.g, becomes: build-1a2B3c4D/**/*) and cached longer

The following files are generated by the following init processors.

  • nbob-config.json - The nBob configuration file
  • .hgignore - Mercurial configuration file
  • .jscsrc - JavaScript Code Style configuration file
  • .jshintrc and .jshintignore - JSHint configuration files
  • __PROJECT__.sublime-project - Sublime Text configuration file
  • xhr-proxy.html - EM XHR Proxy (load in iframe to enable cross origin XHR)
  • browserslist - Browserslist config file for Post CSS Autoprefixer etc.
  • ~/.aws/credentials - Amazon Web Services credentials configuration file