Update July 15th 2013: Due to commenters demand, we have re-published this research as a Git repository anybody can contribute to: github.com/Seravo/js-winning-style. This article has become our most popular article with over 10 000 unique readers, so this issue is clearly something the JavaScript community should get done.
Update August 16th 2013: A translation in Russian has been published at Habrahabr.ru and it has over 12 000 views. A Chinese translation has been published at liruobing.cn and guochengyao.cn. The updated version at GitHub has been written by 4 new contributors. Thanks everybody!
Update November 11th 2013 There is now a project called Popular coding conventions on GitHub which analyzes (among others) recent JavaScript code and how popular different coding styles are. We are pleased to note that the style recommendations presented in our article match the results found in the GitHub analysis.
If your code is easy to read, there will be fewer bugs, any remaining bugs will be easier to debug and new coders will have a lower barrier to participate in your project. Everybody agrees that investing a bit of time following an agreed-upon coding style is worth all the benefits it yields. Unlike Python and some other languages, JavaScript does not have an authoritative style guide. Instead there are several popular ones:
- Google JavaScript Style Guide
- npm’s coding style
- Felix’s Node.js Style Guide
- Idiomatic JavaScript
- jQuery JavaScript Style Guide
- Douglas Crockford’s JavaScript coding style
Then of course, there are also the default settings chosen in JavaScript syntax checkers JSLint and JSHint. The question is, what is the ultimate JavaScript style to rule them all? Let’s make a consensus based on these six style guides.
Indentation
Two spaces, not longer and no tabs: Google, npm, Node.js, Idiomatic
Tabs: jQuery
Four spaces: Crockford
Spaces between arguments and expressions
Use sparingly like below: Google, npm, Node.js
project.MyClass = function(arg1, arg2) {
Use generous white space like below: Idiomatic, jQuery
for ( i = 0; i < length; i++ ) {
No expressed opinion: Crockford
Many guides remind not to have any trailing spaces!
Line length
Max 80 characters: Google, npm, Node.js, Crockford
When wrapping, other indentation than two spaces is allowed to for example align function arguments to the position where the first function argument was. Another option is to use four spaces instead of two when word wrapping long lines.
No expressed opinion: jQuery, Idiomatic
Semicolons
Always use semicolons and don’t rely in implicit insertion: Google, Node.js, Crockford
Don’t use except on some situations: npm
No expressed opinion: jQuery, Idiomatic
Comments
JSDoc conventions: Google, Idiomatic
In the Idiomatic Style Guide also simpler comments are allowed, but JSDoc encouraged.
No expressed opinion: npm, Node.js, jQuery, Crockford
Quotes
Prefer '
over "
: Google, Node.js
Double quotes: jQuery
No expressed opinion: npm, Idiomatic, Crockford
Variable declarations
One per line and no commas: Node.js
var foo = '';
var bar = '';
Multiple in one go with line ending commas like below: Idiomatic, jQuery
var foo = '',
bar = '',
quux;
Start with comma: npm
var foo = ''
,bar = ''
,quux;
No expressed opinion: Google, Crockford
Braces
Use opening brace on the same line: Google, npm, Node, Idiomatic, jQuery, Crockford
function thisIsBlock() {
These also imply that braces should be used in all cases.
The npm style guide states that braces should only be used if a block needs to wrap to the next line.
Globals
Don’t use globals: Google, Crockford
Google says: “Global name conflicts are difficult to debug, and can cause intractable problems when two projects try to integrate. In order to make it possible to share common JavaScript code, we’ve adopted conventions to prevent collisions.”
Crockford states that implied global variables should never be used.
No expressed opinion: Idiomatic, jQuery, npm, Node
Naming
Variables
Start first word lowercase and after that all words start with uppercase letter (Camel case): Google, npm, Node, Idiomatic
var foo = '';
var fooName = '';
Constants
Use uppercase: Google, npm, Node
var CONS = 'VALUE';
var CONSTANT_NAME = 'VALUE';
No expressed opinion: jQuery, Idiomatic, Crockford
Functions
Start first word lowercase and after that all words start with uppercase letter (Camel case): Google, npm, Idiomatic, Node
Prefer longer, descriptive function names.
function veryLongOperationName()
function short()
Use vocabulary like is, set, get:
function isReady()
function setName()
function getName()
No expressed opinion: jQuery, Crockford
Arrays
Use plural forms: Idiomatic
var documents = [];
No expressed opinion: Google, jQuery, npm, Node, Crockford
Objects and classes
Use Pascal case (every word’s first letter is capitalized): Google, npm, Node
var ThisIsObject = new Date();
No expressed opinion: jQuery, Idiomatic, Crockford
Other
Use all-lower-hyphen-css-case
for multi-word filenames and config keys: npm
Suggested .jshintrc file
JSHint (http://www.jshint.com/) is a JavaScript syntax and style checker you can use to alert about code style issues. It integrates well into to many commonly used editors and is a nice way to enforce a common style. See JS Hint documentation for all available options: http://www.jshint.com/docs/#options Below we have created a .jshintrc
file that follows the recommendations set above in this article. You can place it in the root folder of your project and JSHint-avare code editors will notice it and follow it though all code in your project.
{ "camelcase" : true, "indent": 2, "undef": true, "quotmark": "single", "maxlen": 80, "trailing": true, "curly": true }
In addition to it you should add into your (browser-read) JavaScript files the following header:
/* jshint browser:true, jquery:true */
In your Node.js files you should add:
/*jshint node:true */
In any kind of JavaScript file it is also good to add the declaration:
'use strict';
This will affect both JSHint and your JavaScript engine, which will become less compliant but run your JavaScript faster.
Automatically JSHint files before Git commit
If you want to make sure that all of your JS code stays compliant to the style defined in your .jshintrc
, you can set the following contents to your .git/hooks/pre-commit
file, which is then run each time you try to commit any new of modified files to the project:
#!/bin/bash
# Pre-commit Git hook to run JSHint on JavaScript files.
#
# If you absolutely must commit without testing,
# use: git commit --no-verify
filenames=($(git diff --cached --name-only HEAD))
which jshint &> /dev/null
if [ $? -ne 0 ];
then
echo "error: jshint not found"
echo "install with: sudo npm install -g jshint"
exit 1
fi
for i in "${filenames[@]}"
do
if [[ $i =~ \.js$ ]];
then
echo jshint $i
jshint $i
if [ $? -ne 0 ];
then
exit 1
fi
fi
done
Happy coding!
This is a useful idea to get some style consensus from the community. However, there are several inaccuracies in the text, particularly with the “no expressed opinion” bits — notably Crockford on Semicolons. He expressed an opinion in his book, “The Good Parts”, JSLint complains when you omit them, and he wrote about it on his blog: http://javascript.crockford.com/code.html#statements
This project would be better on Github – like Idiomatic.js, where anybody can fork it or file issues to correct inaccuracies, or add things that are missing from your list.
Perhaps add an update to the top of this article linking to the github page. “Add updates and corrections here” or something.
Article updated: Crockford is now mentioned as one of the recommenders of the always semicolon style.
I contacted the author of Idiomatic.js but he seems to like very much his current style guideline, and changing something to be more like what the majority does didn’t seem like a compelling idea to him.
Starting a new project or forking Idiomatic.js and updating these findings into it does not sound compelling to us, as there would be too much marketing effort required to make any new style guide meaningful.
We still hope this blog article helps anybody thinking about what style to adopt to their own projects.
My suggestion is that you move this project to Github so that the community can help you improve it. There are still some errors that need fixing, and it would be much easier if I could just fork it, correct errors myself, and send you a pull request.
As you requested: https://github.com/Seravo/js-winning-style
Feel free to continue it by fixing errors, adding comparison items, do general styling or do whatever you want.
Great article, Otto
The result in “Variable Declarations” makes me wonder why “One per line and no commas” wins when it’s only supported by Node.js, where “Multiple in one go with line ending commas” is supported by Idiomatic and jQuery, and even Crockford in his book (check Section 2.5.)
I wondered the same thing. “Let’s make a consensus based on these six style guides” would suggest “Multiple in one go with line ending commas” should be the style used. I’m wondering if this is a mistake in the blog post?
I think the one “var” with multiple declarations has an interesting plus: its more like object declarations:
var foo = 10,
bar = 42;
is similar to:
var obj = {
foo: 10,
bar: 42
}
i.e. NOT
var obj = {};
obj.foo = 10;
obj.bar = 42;
I don’t get the
Objects and classes
Use like below: Google, npm, Node var ThisIsObject = new Date;
If the var is an object, I would most certainly start it with lowercase, like
var thisIsObject = new Date;
I would ONLY use UpperCase if it’s a constructor function meant to be used with the new Operator, like
var ThisIsPseudoClass = function() { this.name = ‘pseudo-class’ }
I agree with this distinction as it it pretty clear in Google’s naming conventions and is consistent in their APIs.
http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml?showone=Naming#Naming
I think this is just a bug in the document. Clearly it should be
var thisIsObject = new Date();
I agree with all of the above. I ESPECIALLY agree with the two space indentation – when frequenting as many coding forums as I do, the tabs are killing and the 4 space indentation pushes a lot of code so far that scrollbars appear.
One thing, I believe that double quotes are now mandatory in JSON in at least Chrome. i.e. { “name”:”some value”}
I personally use single quotes if I wrap html, since I always use double quotes around html attributes
Have you thought of writing a brackets.io or an eclipse formatter for the same?
Regardless of spaces or tabs for indentation, what lead you to go with an indentation size of 2 spaces.
Indentation in JavaScript is purely to increase readability, right? So why would you decide on an indentation size of slightly greater than flush left?
I’ve coded in all of the mentioned styles, and the 2 space indentation was by far the most difficult to read.
All-in-all, good article comparing the popular style guides, keep it up.
Additionally jQuery, Node.js, and npm style guides recommend trimming trailing whitespace (including disallowing whitespace on blank lines).
None of them seem to state an opinion on Windows vs. Unix line endings or whether files should contain a final newline. jQuery’s .editorconfig file seems to imply they prefer linefeeds and final newlines and I expect this style is preferred by most projects: https://github.com/jquery/jquery/blob/master/.editorconfig#L7
The ‘Objects and classes’ part is pretty obscure.
var ThisIsObject = new Date;
It’s just a variable! Why start its name with an upper case letter?
I think, you had to write that names of the functions that are to be used as constructors should start with an upper-case letter.
Good article! The only part that through me off, was the part about the braces:
function thisIsBlock(){
I hope you meant it like this:
function thisIsBlock() {
(note the whitespace)
Otherwise I can sign that. The only problem that Germans have is that ‘ is much harder to type than “. But I guess you get used to it.
I agree with most of this but the two space indentation may be a consensus with a few guides you’ve looked at but the consensus amongst programmers for any bracketed language seems to be tabs by a large margin. I have yet to see a single valid argument in my days where spaces offer a benefit over tabs, let alone enough beneficial arguments to win out against tabs.
I’d list out the arguments but it’s been done to death on stack.
http://programmers.stackexchange.com/questions/57/tabs-versus-spaceswhat-is-the-proper-indentation-character-for-everything-in-e
I think that the “ultimate style to rule them all” doesn’t really exist. While many guides comes with rationale, some of them are also matters of personal taste (style) and the backgrounds they came from.
People who are used to write PHP/Java which require semicolons may prefer semicolons in their JavaScript code, while people who have Python/Ruby background may not prefer semicolons. Now the argument for both of can be that it’s easier to read, but it’s easier to read just because their eyes are used to see or not see a semicolon at the end of statements.
The fact that most people uses a certain style doesn’t make it the best, or the ultimate style to rule them all. That’s argumentum ad populum. It’s like saying that since a majority of webpages have white background, so it’s suggested that you make webpages with white background.
I think it’s best just to be consistent. I’d just pick a style that makes my code most comfortable and easy to read for myself (background and personal tastes all take part in this decision), and be consistent with it for that particular project.
The value of “quotmark” should be “single” (wrapped in double quotes) in the sample .jshintrc file.
I don’t see anyone on the google style guide that suggests 2 white spaces vs tabs.
I suppose it’s inevitable that an article on style will have comments full of nitpickery (or pedantry, if you prefer). Here are mine, both on the same point:
You say “Use exessive white space like below”
1. excessive is not spelled exessive (it was hard to type it wrongly)
2. Using a term like excessive implies that there is something wrong with it, rather than being a valid option. Perhaps ‘generous’ would be better.
Should have added that I will be trying out your combined style and investigating Idiomatic.
Thanks
I think that section “Object & Classes” in not correct. Classes (construction function) should always be named with first letter uppercase.
But instance (variable) should always start with lowercase:
var point = new Point();
That way it is always clear what is class (constructor) and what is instance.
A translation in Russian has been published at Habrahabr.ru and it has over 4000 views. A Chinese translation has been published at liruobing.cn and guochengyao.cn. The updated version at GitHub has been written by 4 new contributors. Thanks everybody!
Here is an extra style checker: https://github.com/mdevils/node-jscs. I just wonder why it was made in addtion of JSHint and not in extension of JSHinta..
Your .git/hooks/pre-commit above has tabs rather than 2 spaces.
Another good argument for setting your editor to “soft tabs” (i.e. use spaces)!
Thanks for the great resource!
— Owen
A new QA automation tool seems to implement most of this JS style guide contents: https://github.com/feross/standard