mad(1) node.js pages
The node.js markdown documentation is now viewable in the terminal via mad(1):

Just use mad list to see which pages are available:

If you already have mad(1) installed simply run mad --update to grab these new pages, and view with mad node.http etc.
Express 3.0.0 alpha1
I just released the first alpha, but beware! the documentation has not been updated. I wanted to defer a release until I had time to re-write the site, but meanwhile people have been using the master branch anyway, so we might as well make it official (and available via npm).
The alpha is by no means complete, some features still need adjusting, though mainly internal refactoring. The wiki contains both the 2.x to 3.x migration guide, and documentation for most of the new features added. It’s worth noting you’ll also gain new features from Connect 2.x as well, which Express 3.x depends on.
There are quite a few new http utilities, better reverse proxy support, and refinements to the view system. Express 3.x is even smaller than 2.x totalling 975 SLOC according to sloc(1), where Express 2.x was around 1300. Most of the effort goes into actually removing and refining code to increase quality, and lots of test coverage (4286 SLOC).
I’ve also started a Express 4.x Roadmap with some details on where things may go in the future.
Contributing
If you’d like to contribute, one of the best ways right now would be to help upgrade the ./examples ! The Express repo has many examples, roughly half of which still use 2.x code and may not work. This time around we have test coverage for these examples, but many still need to be upgraded. To contribute first install the development dependencies:
$ npm install
Then run the acceptance tests:
$ make test-acceptance
Add some tests for an example, write some tests, make sure they work, then open a pull-request :)
That’s all for now! When I have time I’ll be rewriting the site, updating the wiki, and of course finishing the release. If there’s anything you find yourself doing often and think has a home in core let me know!
cheers!
EDIT: If you’re looking for docs we now have some auto-generated docs that you can view in your terminal. View this post.
Redis Lua scripting is badass
Roughly a year ago Salvatore Sanfilippo the author of Redis
wrote a blog post
discussing the inclusion of Lua as a scripting language. I
finally decided to try this out, and let’s just say it’s pretty badass.
Lua is a great fit for Redis, they have similar philosophies, being simple,
small, and fast. Suppose for example you have 200,000 jobs, each represented
in Redis as a hash, and you want to map/reduce the job duration, the new scripting
capabilities make this really easy!
Here’s the node setup script to generate these jobs:
var redis = require('redis')
, db = redis.createClient();
var n = 500000
, pending = n
, ms;
while (n--) {
ms = Math.random() * 200 | 0;
db.hset('job:' + n, 'duration', ms, function(){
--pending || process.exit();
})
}
Next here is what you might consider scripting in your host language
without the new Redis scripting feature, manually reducing the value:
var redis = require('redis')
, db = redis.createClient();
var n = 200000
, start = new Date
, pending = n
, ms = 0;
while (n--) {
db.hget('job:' + n, 'duration', function(err, n){
if (err) throw err;
ms += ~~n;
--pending || (function(){
console.log('%d minutes spent processing jobs', ms / (1000 * 60) | 0);
console.log('took %ds', (new Date - start) / 1000 | 0);
process.exit();
})();
})
}
On my Air this took roughly 7s, not too great, keep in mind that there is no throttling here I’m just plastering it with 200k commands. Now let’s try it with Lua! The
following script is ad-hoc, but it’ll do the trick. To signal an error all you
have to do is return a table with the err slot. redis.call() is effectively
the public Redis API exposed to your Redis script, so you can use it just like you
would your host language Redis bindings or redis-cli(1).
local sum = 0
for i = 0, 200000, 1 do
local key = "job:" .. i
local ms = tonumber(redis.call("hget", key, "duration"))
if ms == nil then return { err = key .. " is not an integer" } end
sum = sum + ms
end
return sum
Here I’ve embedded it in the JS script, but you could of course generate these,
load them from files etc (beware of redis-injection?).
var redis = require('redis')
, db = redis.createClient();
var script = '\
local sum = 0 \
for i = 0, 200000, 1 do \
local key = "job:" .. i \
local ms = tonumber(redis.call("hget", key, "duration")) \
if ms == nil then return { err = key .. " is not an integer" } end \
sum = sum + ms \
end \
return sum';
var start = new Date;
db.eval(script, 0, function(err, ms){
if (err) throw err;
console.log('%d minutes spent processing jobs', ms / (1000 * 60) | 0);
console.log('took %dms', new Date - start | 0);
process.exit();
});
After running the script with the new EVAL command what previously took
several seconds dropped to ~850ms, much better. EVAL and EVALSHA
are actually a lot more flexible than I’ve explained here, accepting keys
and arbitrary arguments.
Check out antirez.com/post/an-update-on-redis-and-lua.html for more.
Mocha string diffs
Mocha 0.14.0 adds a single feature - string diffs! This is a small but very handy feature for some. When the strings are small, Mocha will use a character diff, when consisting of several lines a line-numbered “gutter” is added and a word diff is used as shown in the following image:

This is very useful when authoring things like template engines, transpilers, and other string-based libraries. For example the Stylus test suite is comprised of nothing but acceptance tests, the input file is compiled, and the resulting CSS is checked using actual.trim().should.equal(css);. In combination with Mocha’s BDD interface I can now simply iterate through the files and define test-cases as shown here:
var stylus = require('../')
, fs = require('fs');
// test cases
var cases = fs.readdirSync('test/cases').filter(function(file){
return ~file.indexOf('.styl');
}).map(function(file){
return file.replace('.styl', '');
});
describe('integration', function(){
cases.forEach(function(test){
var name = test.replace(/[-.]/g, ' ');
it(name, function(){
var path = 'test/cases/' + test + '.styl';
var styl = fs.readFileSync(path, 'utf8');
var css = fs.readFileSync('test/cases/' + test + '.css', 'utf8');
var style = stylus(styl)
.set('filename', path)
.include(__dirname + '/images')
.include(__dirname + '/cases/import.basic')
.define('url', stylus.url());
if (~test.indexOf('compress')) style.set('compress', true);
style.render(function(err, actual){
if (err) throw err;
actual.trim().should.equal(css);
});
})
});
})
Now if something were go to wrong, you get a nice diff!

Assertion library authors
To support this feature all you have to do is populate err.expected and err.actual with their respective values, Mocha will take care of the presentation.
NOTE: I just toggled the colors, green is now the expected color
commander.js - nodejs command-line interfaces made easy
Commander.js is a small node.js module allowing you to define options and interacte with the user’s terminal in a simple and natural way, inspired by the Ruby library of the same name.
Features
- self-documenting code
- auto-generated help
- combined short flags (“-abc” == “-a -b -c”)
- option defaults
- option coercion
- command parsing
- prompts
Example
A basic commander program looks something like the following (taken from serve). It’s extremely easy to see what’s going on, all the options provided by the executable are laid out infront of you.
program
.version('0.0.1')
.option('-p, --port <port>', 'specify the port [3000]', Number, 3000)
.option('-H, --hidden', 'enable hidden file serving')
.option('-I, --no-icons', 'disable file icons')
.option('-L, --no-logs', 'disable request logging')
.parse(process.argv);
In the previous example only --port accepts an argument, and the value of program.port defaults to 3000. The options --no-icons and --no-logs default their properties to true, only when --no-icons is specified will program.icons be false.
The usage information is free!:
$ serve --help
Usage: serve [options]
Options:
-v, --version output the version number
-p, --port <port> specify the port [3000]
-H, --hidden enable hidden file serving
-I, --no-icons disable file icons
-L, --no-logs disable request logging
-h, --help output usage information
Utilities
Commander is bundled with some utilities for prompting user input, confirmations, passwords, lists of choices etc. Most of these utilities will ask for input if the user simply hits enter and should respond.
Below is an example of asking for a name using a single-line input prompt:
program.prompt('name: ', function(name){
console.log('hi %s', name);
});
Multi-line input is easy too, just leave out the trailing space in the message:
program.prompt('description:', function(name){
console.log('hi %s', name);
});
Coercion is useful for dates, numbers etc:
program.prompt('Age: ', Number, function(age){
console.log('age: %j', age);
});
Password prompts masking off input:
program.password('Password: ', function(pass){
console.log('got "%s"', pass);
});
Or providing a mask char:
program.password('Password: ', '*', function(pass){
console.log('got "%s"', pass);
});
Confirmations require “yes” or “y” to result in true:
program.confirm('continue? ', function(ok){
console.log(' got %j', ok);
});
There’s also choice support, so users can select from a list:
var list = ['tobi', 'loki', 'jane', 'manny', 'luna'];
console.log('Choose the coolest pet:');
program.choose(list, function(i){
console.log('you chose %d "%s"', i, list[i]);
});
presenting:
Choose the coolest pet:
1) tobi
2) loki
3) jane
4) manny
5) luna
Commands
Though I haven’t had time to polish them up yet, commander supports the idea of .. well… “commands”. The “root” executable is an instanceof Command, and well you can recursively define these to create a rich interface. GIT is a great example of this, many larger utilities use sub-command such as git remote to accept arguments, and may all then have their own options etc, using the same API as the root command. The following is a simple example:
#!/usr/bin/env node
var program = require('../');
program
.version('0.0.1')
.option('-C, --chdir <path>', 'change the working directory')
.option('-c, --config <path>', 'set config path [./deploy.conf]')
.option('-T, --no-tests', 'ignore test hook')
// $ deploy setup stage
// $ deploy setup
program
.command('setup [env]')
.description('run setup commands for all envs')
.action(function(env){
env = env || 'all';
console.log('setup for %s env(s)', env);
});
// $ deploy stage
// $ deploy production
program
.command('*')
.action(function(env){
console.log('deploying "%s"', env);
});
program.parse(process.argv);
Moar Libraries!
Dont forget to check out these other great CLI-related libraries: