npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

tower-style-guide

v0.0.1

Published

## General Documentation Semantics

Downloads

3

Readme

Tower Style Guide

General Documentation Semantics

  • Write in a conversational style.

    • Use pronouns: I, we, you, they.
    • Use colloquial expressions: a sure thing, turn-on, rip-off, OK.
    • Use contractions: they're, you're, it's, here's, we've, I'm.
    • Use simple words.
    • If you must choose between writing naturally and being grammatically correct, write naturally.
    // yay
    I'm going home.
    It's simple.
    
    // nay
    I am going home.
    It is simple.

JavaScript

  • Define var one at a time (don't use leading/trailing commas):

    // yay
    var event = require('event');
    var dom = require('dom');
    var assert = require('assert');
    
    // nay
    var event = require('event'),
        dom = require('dom'),
        assert = require('assert');
    
    // nay
    var event = require('event')
      , dom = require('dom')
      , assert = require('assert');

    While the later two are minimally more optimized, minifiers like uglifyjs will make these optimizations for you. So write what is most human readable.

  • Use trailing commas for multi-line arrays.

    // yay
    var events = [
      'click',
      'keypress',
      'focusin',
      'focusout'
    ];
    
    // nay
    var events = [
        'click'
      , 'keypress'
      , 'focusin'
      , 'focusout'
    ];
  • Use trailing commas for multi-line objects.

    // yay
    var styles = {
      color: '#000',
      background: '#fff',
      width: 100,
      height: 200
    };
    
    // nay
    var styles = {
        color: '#000'
      , background: '#fff'
      , width: 100
      , height: 200
    };
  • Always use " double quotes when declaring JSON keys and values.

    // yay
    {
      "myKey": "string",
      "myArray": ["some stuff", "more stuff"]
    }
     
    // nay
    {
      myKey: 'string',
      'myArray': ['some stuff', 'more stuff']
    }
  • For strings that are not defined in JSON, default to declaring strings with ' single quotes. In the case where your string contains special format characters or ' single quotes, use " double quotes.

    // yay
    var str = '"Marty" is at the party!';
    var specialStr = "im'oto";
    
    // nay
    var str = "\"Marty\" is at the party!";
    var specialStr = 'im\'oto';
  • For assigned functions, have no whitespace between parentheses and brackets: ){ vs. ) {.

    // yay
    exports.init = function(){
      this.x;
    };
      
    // nay
    exports.init = function() {
      this.x;
    };
  • For callback functions, do the same thing.

    // yay
    route('/users')
      .on('exec', function(){
    
      });
      
    // nay
    route('/users')
      .on('exec', function() {
    
      });
  • For non-assigned functions, do it the other way around.

    // yay
    function init() {
      this.x;
    };
      
    // nay
    function init(){
      this.x;
    };

    This distinguishes the function declarations and function expressions.

  • Indent DSL methods if they are in a new object scope.

    // yay
    adapter('facebook')
      .model('user')
        .attr('username')
        .action('create')
        .action('find')
          .param('page', 'integer')
      .model('like');
      
    // nay
    adapter('facebook')
      .model('user').attr('username').action('create')
      .action('find')
      .param('page', 'integer')
      .model('like');      
  • Keep 1 space between native methods and parentheses (if, while, for, etc.).

    // yay
    if (x) y();
    
    // nay
    if(x) y();
  • Emit event names in the present tense as verb [object|property].

    // yay
    this.emit('define', user);
    this.emit('define user', user);
      
    // nay
    this.emit('defined user', user);
    this.emit('user defined', user);
    this.emit('user define', user);
  • Emit namespaced events from most generic to most specific. This way, you can mixin more generic stuff first, and use those generic methods on specific objects.

    // yay
    this.emit('define', user);
    this.emit('define facebook', user);
    this.emit('define facebook.user', user);
      
    // nay
    this.emit('define facebook.user', user);
    this.emit('define facebook', user);
    this.emit('define', user);
  • Pass the this as context for the first parameter in DSL methods, instead of using this as a reference. The context is stated more clearly.

    // yay
    route('/users')
      .on('request', function(context, next){
        context.render();
      });
    
    // nay
    route('/users')
      .on('request', function(next){
        this.render();
      });
  • Place the compared value on the left instead of the right. This is unnatural at first, but it makes the code much easier to read for a newcomer.

    // yay
    if ('string' === typeof(x))
      exec();
    
    // nay
    if (typeof(x) === 'string')
      exec();

    The reason for this is, the compared-to value (e.g. 'string') is first, so it reads if ('string') exec().

  • Leave 1 empty line at the *top of each file.

    \n
    /**
     * Blank line above.
     */
    /**
     * No blank line above
     */
  • Leave 0 empty lines at the bottom of each file.

  • Leave 1 blank line between comments and code.

    /**
     * GOOD
     */
    
    exports.init = function(){
    
    };
    /**
     * BAD
     */
    exports.init = function(){
    
    };
  • For loops should be as efficient and clean as possible.

    // yay
    for (var i = 0, n = arr.length; i < n; i++) {}
    
    // nay
    for (var i = 0; i < arr.length; i++) {}

    Single letter variables should only be used within loops (basically for loops).

     // yay
     for (var i = 0, n = arr.length; i < n; i++) {}
    
     // nay
     for (var index = 0, size = arr.length; index < size; index++) {}
  • For each loops (for loops but with objects) should have safe guards, which is a general good JavaScript practice.

    // yay
    for (var key in obj) {
      if (obj.hasOwnProperty(key)) {
        delete obj[key];
      }
    }
    
    // nay   
    for (var key in obj) {
      delete obj[key];
    }
  • Use obj.init() instead of new Obj, where obj.create() should do some db/service call.

    // yay
    var newObj = obj.init();
    
    // nay
    var newObj = new Obj();
  • For single-line arrays and objects, put one space before/after containing brackets.

    // yay
    [ 'i386', 'x86_64' ]
    { status: 'active' }
    
    // nay
    ['i386', 'x86_64']
    {status: 'active'}
  • Avoid aligning signs such as =, :, etc. The reason is, while it does create some symmetry, it makes the code a little harder to read.

    // yay
    var x = 1;
    var foo = 'bar';
    var hello = 'world';
    
    // nay
    var x     = 1;
    var foo   = 'bar';
    var hello = 'world';
  • If a ternary statement is too long, put it on multiple lines with ? and : at the start of the line.

    // yay
    exports.query = function(name){
      return null == name
        ? query().start(this.className)
        : query(name);
    }
    
    // nay
    exports.query = function(name){
      return null == name ?
        query().start(this.className) :
        query(name);
    }
  • If you are building a multiline string, use + at the beginning of the line.

    // yay
    var string = 'some '
      + 'long '
      + 'string ';
    
    // nay
    var string = 'some ' +
      'long ' +
      'string ';
    
    // nay
    var string = 'some \
      long \
      string ';

    In EcmaScript 6, you'll be able to use backticks for multi-line strings.

Repos

  • Name your projects using lowercase with hyphens.
    // yay
    var myProject = require('my-project');
    
    // nay
    var myProject = require('myProject');
    var myProject = require('MyProject');

Events

These are all of the events used in Tower. When creating custom APIs, see if these events can be used before defining another. Maybe we can even cut it down.

emit('define');
emit('init');
emit('exec');
emit('open');
emit('close');
emit('connect');
emit('disconnect');
emit('render');
emit('request');
emit('error');
emit('data');

Maybe route.on('request') becomes route.on('exec'). And route.on('connect') becomes route.on('open').

Tests

  • Use easy to scan/understand syntax for assertions.
    // yay
    assert(true === val);
    assert(false === val);
    assert('foo' === val);
    assert(undefined === val);
    
    // nay
    assert.isTrue(val);
    assert.isFalse(val);
    assert.equal('foo', val);
    assert.isUndefined(val);
    // - should syntax
    val.should.be(undefined);

Comments

  • Here is the general structure of a good comment:
    /**
     * Iterate each value and invoke `fn(val, i)`.
     *
     *    users.each(function(val, i){
     *
     *    });
     *
     * @param {Function} fn
     * @return {Object} self
     * @api public
     */
    
    proto.forEach = function(fn){
      // ...
      return this;
    };

Readme Structure

The basic format:

  • Title
  • Installation
  • Examples (optional)
  • API
  • Running Tests
  • Contributing
  • Notes (optional)
  • License

Examples

  • https://github.com/component/struct/blob/master/index.js
  • https://github.com/component/pipe/blob/master/index.js
  • https://github.com/component/raf/blob/master/index.js
  • https://github.com/component/to-function/blob/master/index.js
  • https://github.com/component/enumerable/blob/master/index.js
  • https://github.com/component/network
  • https://github.com/component/trace/blob/master/index.js
  • http://stackoverflow.com/questions/5495984/coding-style-guide-for-node-js-apps