
Airbnb JavaScript Style Guide - webnanners
https://github.com/airbnb/javascript
======
brwnll
The best part of this guide is that they included a eslint and jslint rules
file.

[https://github.com/airbnb/javascript/tree/master/linters](https://github.com/airbnb/javascript/tree/master/linters)

My team adopted this style guide and was easily able to add it as a eslint
step to our existing gulp files and run it automatically. This let us use the
guide without making everyone memorize the syntax differences between their
personal style first.

------
elisee
Regarding using single quotes for strings
([https://github.com/airbnb/javascript#6.1](https://github.com/airbnb/javascript#6.1)),
I found it interesting that it's one of the rare sections where there's no
rationale offered.

I guess it's just a stylistic choice in the end, but when we set up our own
internal/informal style guide, my teammate and I spent a little while trying
to come up with a justification for single vs double quotes. We ended up
choosing double quotes based on the fact that JSON already made that decision
for us: it requires strings be double-quoted.

(Although again, it's far from an important matter, as long as you're
consistent), anybody has interesting rationales to share in favor of single
quotes?

~~~
YorkianTones
If you use contractions like don\'t inside of a string then you need to escape
the apostrophe if you\'re using single quotes, which is annoying and can make
the string a bit harder for humans to parse. I like the aesthetics of double-
quotes better too, though that\'s not a compelling reason.

~~~
elros
Well, one simple typographical way to solve this is not to use a quotation
character (') when what is meant is an apostrophe character (’).

~~~
recmo
"Don’t say “Hello”"

Proper typography solves all.

My toy programming language uses “ and ” for string literals. It counts
nesting, so you can write “Don’t say “Hello””. There is no escaping. In fact,
you can quote any piece of code by simply enclosing it in “ and ”. Code is
commented out by turning it into an unused string literal.

------
svieira
The fact that `typeof` is no longer safe [1][2] is news to me - it feels like
they put in air bags and removed the seat belts.

    
    
      [1]: https://github.com/airbnb/javascript#14.1
      [2]: http://es-discourse.com/t/why-typeof-is-no-longer-safe/15

~~~
AgentME
The only code affected by this would be code that uses typeof to check for the
existence of a variable the same code defines later, which sounds like dumb
code to begin with. I don't think there's any valid uses of typeof on possibly
undefined variables besides checking for browser built-ins.

~~~
mAritz
Using typeof(foo) === "undefined" is actually something that comes from back
when it was pretty common to pollute the global namespace. There were actual
javascript plugins/libraries/snippets that defined undefined and thus broke
code that compared to it.

------
BinaryIdiot
Looks like a lot of good stuff but it's incredibly verbose and dense. It's
important to adhere to standards but I'm not entirely convinced this doesn't
end up being counter-productive. But as long as it's a guide and not a 100%
"you must follow every little thing" and you can change things then maybe it's
not so bad.

Still hard to get used to so many using ES6 already. I'm still not a big fan
of transpiling but some days I feel like I'm the only one.

~~~
Todd
Yes, there is a mix of pragmatic advice (with citations) along with stylistic
opinions. I think the ES5 version is also quite good. Look at the number of
forks, though. I might use this as the basis for a style guide for my
organization. I think I'll probably fork it, though, and remove the
opinionated bits. I did enjoy the writing style.

------
tehwebguy
I didn't know you could do this!

    
    
          // good
          const obj = {
            id: 5,
            name: 'San Francisco',
            [getKey('enabled')]: true,
          };

~~~
natrius
Next to arrow functions and optional arguments, better object syntax is one of
the big reasons you should be using Babel today. You know how sometimes you
need to precalculate values that are going to be returned in an object, so at
the end of the function, you return something like this?

    
    
      return {
        foo: foo,
        bar: bar,
        baz: baz
      };
    

You don't have to do that in ES6.

    
    
      return {foo, bar, baz};
    

Keys without values use variables with the same name as their values.

------
z3t4
I love these kind of style guides. But I also love to prove them wrong.

Unless you "use strict", it's better to put var in-front of every variable if
you put them on separate lines.

    
    
      var foo = 1,
          bar = 2
          baz = 3
    

vs

    
    
       var foo = 1;
       var bar = 2;
       var baz = 3;
    

Forgetting a comma or semicolon in the first example might lead to silent bugs
that will take hours to find.

~~~
savanaly
Isn't this exact rule already in the guide?

[https://github.com/airbnb/javascript#13.2](https://github.com/airbnb/javascript#13.2)

~~~
z3t4
Ahh, someone might just have added it to troll me, or I'm crazy.

------
eltaco
You can use the airbnb preset with JSCS (javascript code style checker) [1].

Also there's an autofix feature for most of the whitespace rules (`jscs src
--preset=airbnb --fix`) so you won't have to fix everything manually.

[1]: [http://jscs.info/overview.html](http://jscs.info/overview.html)

------
cnp
This is the ES6 guide I send around to those who are trying to get up to speed
with JavaScript -- its fantastic.

------
z3t4
About referencing "this": It can be very useful when writing object
constructors, if you always reference an object with the constructor's name.

    
    
      function Foo() {
        var foo = this;
        foo.bar = 1;
        foo.az = 2;
      }
    
      var foo = new Foo();
      foo.bar = foo.bar + 5;
    

Then it will be super easy to rename say foo.bar to something else. It's also
self "documented".

------
heydanreeves
There's also a jscs default for this styleguide.

    
    
        {
            "preset": "airbnb"
        }

------
ewalk153
There is also a link on the page to browser compat style guide of es5
[https://github.com/airbnb/javascript/tree/master/es5](https://github.com/airbnb/javascript/tree/master/es5)

------
neebz
Does anybody have experience integrating style guides in your existing code
base?

Our old code base doesn't follow any style guide. After adding a style guide
it requires us to go back and fix all our old files which is time consuming +
kinda messes up with the git history.

~~~
mik3y
Yes: Check in a unittest that runs your linter, and check in the config as
well (eg jshintrc). Tackle all the flagrant style issues until the test
passes.

------
liviu
_" Recommend using .jsx extension for React components, rather than .js"_

I like .js over .jsx because I can require/import without explicit extension.

    
    
      import Foo from './Foo';
      vs 
      import Foo from './Foo.jsx';

~~~
fit2rule
Great, so you'll never be quite sure whether that module is a plain ol'
javascript, or contains React-extended components... eventually it'll all
blend together and you won't have much awareness, say .. a year or so after
you've put the code to bed .. what is where and how ..

~~~
liviu
Not really. In a real-case scenario React-extended components stays in
"components" directory and is not to hard to be aware that is react-extended
component.

But yes, I got your point.

------
orthoganol
Why are they worried about working by reference on numbers?

    
    
      // bad
      var a = 1;
      var b = 2;
    
      // good
      const a = 1;
      const b = 2;

~~~
epidemian
In JS `const` just means that you can't reassign that variable, not that the
value it references can't change:

    
    
      const a = {foo: 5};
      a.foo = 42; // This is perfectly valid.
      a = 'nope'; // But this isn't. It raises a SyntaxError.

~~~
anselmoars
'const' is misleading, it doesn't set your variables as immutable. Fine for
expression, but not for actual practicality.

~~~
icebraining
It does set your variables as immutable, just not your values. It makes sense
if you see variables in these languages for what they are: references to
values.

------
TheAceOfHearts
As an alternative style guide, consider giving standard [0] a try. The hook
is: "No decisions to make. No .eslintrc, .jshintrc, or .jscsrc files to
manage. It just works." You don't have to configure anything, you just run it
on your project and it'll tell you what to change.

[0] [https://github.com/feross/standard](https://github.com/feross/standard)

------
seniorsassycat
I'd like to see the justifications for some of these, particularly 3.5 which I
see as only obscuring that the current context is a function.

~~~
savanaly
Major advantage: fewer characters to type and parse (parse with your eyes,
that is).

Major disadvantage: in the short term it might be difficult to parse.

Possible additional major disadvantage: programmers may never adapt and find
it difficult to parse for ever more.

~~~
atinoda-kestrel
Yeah, I'm not sold on "fewer characters" as a win. 'cause then we can have the
code golf arguments that inevitably get into the nutty realm.

For visual parsing, consistency matters. In an object literal dec I expect:

    
    
      name : value
    

That's easy to parse visually. Not good is when suddenly we get:

    
    
      nameandvalue(){
    

in the space that our brain expects the former.

------
bshimmin

       3.3 Use readable synonyms in place of reserved words.
    
       // bad
       const superman = {
         class: 'alien',
       };
    
       // bad
       const superman = {
         klass: 'alien',
       };
    

What is unreadable about "klass"? Rails, for example, uses "klass" and it's
never been hard for me (or, I suspect, anyone) to understand.

~~~
jbergens
They probably don't mean 'class' in the programming language sense and should
therefore use another name.

~~~
adrusi
Well maybe they _are_ using "class" in the OOP sense, for instance if they're
implementing a programming language. Even if they're not, if they use the word
"class" in the specification for what they're implementing (maybe they're
representing a taxonomical hierarchy in their program and have fields named
"kingdom", "phylum", "class", etc), or have the word "class" in a user facing
output (maybe they're making an RPG where a character object has fields
"race", "class", "level").

It's confufing to use one name inside your code and different one elsewhere.

------
dkrvt
I'm curious as I haven't found a good coding style guide about object
inheritance in ES5.

I usually write this even though it's a bit verbose:

    
    
      function Child() {
        Parent.call(this);
      }
      Child.prototype = Object.create(Parent.prototype);
      Child.prototype.constructor = Child;
    

Any opinion on this or link to a good guide?

~~~
yefim
ES6 actually solves this with it's new Class syntax.

    
    
      class Child extends Parent {
      }

------
ilaksh
So basically they could have just written "use all of the new features except
these three things..".

------
BurningFrog
Maybe this is the IPA talking, but I don't think I ever want to work at a
company with a style guide again.

This is no worse that others I've seen, but they all codify what some group
found useful at some point in time, and then that becomes Company Policy set
in stone for the rest of time.

~~~
forrestthewoods
The alternative is that every coder has their own style and over time every
file becomes random and wildly inconsistent. That doesn't sound good to me
either.

~~~
atinoda-kestrel
There's a middle ground though.

On my team, the long-standing rule is that you need to make a best effort to
stick to the module's existing style. So we're not gonna bust your balls
because you don't split at exactly 100 characters or whatever... but if you
never wrap your lines and if you insist on indenting things completely
differently than everyone else then yeah, you're creating a problem.

It also helps that our "style guide" is pretty minimal. Brace conventions,
indentation, spaces before conditions, etc. Things that have a serious impact
on readability and ease of debugging and that can easily be auto-formatted.
What we don't specify is the higher order stuff -- _provided_ you are
internally consistent. We don't mind if API A uses one naming scheme and API B
uses another, provided that we don't have a mix of different ones in the same
API. Same for how something like object extension is handled. This falls into
the realm of "we assume our developers will make the best technical choice",
but so far it works.

There's always a complaint that specifying the braces, spacing, etc. is
stupid, and if it required a lot of human intervention or was treated as a
serious offense I'd agree. For us it doesn't, and it's not. The purpose is to
limit the amount of visual friction when switching from one file to another.
_What_ the code is doing is the important part -- presentation should be as
uniform as possible to limit distraction. Add in the fact that we've got an
Eclipse profile with all the spacing, etc. setup the way that we do it, and
it's pretty easy to keep things tidy.

------
lewisjoe
[http://stackoverflow.com/questions/21545687/javascript-vs-
ne...](http://stackoverflow.com/questions/21545687/javascript-vs-new-object-
performance)

-explains why {} is better than new Object().

------
nailer
Alternatively, idiomatic.js
[https://github.com/rwaldron/idiomatic.js/](https://github.com/rwaldron/idiomatic.js/),
an older publication with more people contributing to it.

------
manojlds
ES5 guide -
[https://github.com/airbnb/javascript/blob/master/es5](https://github.com/airbnb/javascript/blob/master/es5)

------
keithwhor
Love this guide. Adhere to it as tightly as possible for most new projects,
saves a lot of mental overhead. Use the ES5 version for team frontend
projects. :)

~~~
shredprez
Amen! Though I am partial to idiomatic.js' whitespace suggestions:

[https://github.com/rwaldron/idiomatic.js#spacing](https://github.com/rwaldron/idiomatic.js#spacing)

Much easier to skim/parse quickly, at least for me.

~~~
nixy
No, no, no, this has to go away. The insertion of spaces before ) and after (
is something I see from time to time in JS code, and it is really difficult
for me to read. Three.js unfortunately uses this, and mrdoob even has his own
style guide. His style guide is probably the only thing I don't like about his
work.

No school I've studied or worked at teaches this style, and JS traditionally
has never been written like this[1][2]. And now I see it elsewhere as well. In
some Java projects, for example. Where does this come from?

There are currently no known hard facts (conclusions from studies) about which
of the whitespace styles have the best readability. So let's just all stick to
the most common way of doing things, shall we :)

    
    
      [1] JavaScript The Good Parts
      [2] Google JS Style Guide http://google.github.io/styleguide/javascriptguide.xml

~~~
chanux
I agree. 'Cramped' there is more 'readable' to me. This is probably a matter
of personal preference.

~~~
Roboprog
Ah, C layout orthodoxy at its finest: shove as much crap separated only by
operators without whitespace on one line as you can. (not exactly what you
said, but I'm extrapolating uncharitably)

I guess you could lampoon me as COBOL orthdoxy, liking spaces between symbols,
but Lisp was good at using whitespace, rather than commas, between symbols as
well.

------
nodesocket
Very nice work, but not sure that I'm onboard with switching `var` to `const |
let`. Is the only difference between `var` and `let` scoping?

~~~
iMark
Not just scoping. The hoisting rules have changed. There's some discussion
earlier in the comments regarding `typeof` no longer being safe to use with
`let` and `const` declarations. `typeof` with a `var` before its declaration
is fine because of hoisting, but with `let` produces a reference error.

~~~
Roboprog
I didn't even know there were "hoisting" rules - I put all my variables on one
var line at the top of the file, then assign them later. Well, except for
lately, function variables in JSDoc work better when the function-var is
immediately assigned :-(

------
da4c30ff

        3.5 Use object method shorthand.
    

I disagree. With anonymous objects it breaks the syntactical uniformity of the
expression. I think it is much clearer when each field is given a name(and a
value) the same way.

------
thomasfoster96
Having seen this updated version I'm not terribly impressed at their guide for
ES6. No mention of symbols (which are pretty important if you're using
classes), generators are ignored almost entirely, a pretty poor explanation of
modules, etc.

~~~
uptown
You're in luck! They published this in GitHub so you can suggest changes you
think might make things better.

~~~
thomasfoster96
Well, style guides are fairly subjective projects compared to most other open
source projects, so while it might be worth my while suggesting things, it's
not likely airbnb is going to change their style guide because I think
differently to them.

Edit: Looking at some issues in the style guide repo, AirBnB seems reluctant
to add or change the style guide to deviate from what they do internally (for
instance, generators are rarely used, therefore they aren't encouraged).

------
berzniz
Styleguides are a matter of taste and there are probably no two people in the
world with the same taste. Was there a voting of this?

------
wnevets
2.2 seems completely arbitrary to me. If your functions are so big that you
need block scope, you're doing it wrong IMO.

~~~
Void_
How else would you use conditions or loops?

~~~
reagency
The style guide doesn't actually use block scope for if/loop.

Many items in the guide are...reasonable, but the explanations are gibberish
or don't match the code.

------
wes-exp
Airbnb's technical quality has been obviously crap for its entire existence.
Why are we taking engineering cues from a glorified room rental site that is
frequently buggy?

~~~
redwards510
Don't think of it as advice from a crappy site. Think of it as developers at a
big company sharing how they do things. Take what you want from it, or just
use it as a conversation jumping off point.

------
joeblow99
// bad const items = new Array();

// good const items = [];

They obviously spent a lot of time on this guide, lots of investor dollars,
and it's of almost no use.

~~~
odabaxok
Imagine this:

a = new Array(10);

b = [10];

alert(a[0]);

alert(b[0]);

Do you know the difference?

This is just one reason. Also [] will be faster. Just google the differences
and why [] is recommended to use.

~~~
ahoge

      > new Array('a')
      ["a"]
      > new Array(2, 3)
      [2, 3]
      > new Array(2)
      [undefined, undefined]
      > new Array(2.3)
      RangeError: invalid array length
      > new Array(2.3, 4.5)
      [2.3, 4.5]
    

The Array constructor is really bogus. It switches to a different mode if a
single number is passed.

ES6 added `Array.of` for this reason:

    
    
      > Array.of()
      []
      > Array.of(1)
      [1]
      > Array.of(1, 2)
      [1, 2]
    

I don't really think it's needed though. Spread and rest already take care of
the common use cases.

------
vivianLTP
I'm a big fan of javascript.

------
joeblow99
// bad const item = new Object();

// good const item = {};

Literally useless differentiation.

~~~
razwall
Seems pretty useful to me. If I see "new Object()", I know the code was
written by someone who doesn't know JS very well, so I should look more
carefully for bugs.

------
jasonkester
I think I'd go nuts in a codebase with their whitespace and brackets rules.

Sure, cramming the opening bracket onto the previous line is just ugly and
something you could learn to live with. But there's a special type of rage
that can only be generated by clicking on to the start of a line and having
your cursor land 1-2 spaces to the left of it.

Why would anybody do that to their code voluntarily?

~~~
ggreer
Some style preferences are subjective, but some have very good reasons for
being the way they are. Here's a simple JavaScript function that returns an
object...

    
    
        function blah()
        {
          return
          {
            key: "value"
          };
        }
    

...except it returns undefined when invoked:

    
    
        console.log(blah());
        undefined
    

Can you spot the bug? With so little code, it should be obvious, right? Before
reading on, stop for a minute and really try to find the error.

...

Figured it out?

...

The answer is that JavaScript has automatic semicolon insertion. That means
there's effectively a semicolon on the same line as return. ASI is why, in
JavaScript, you _always_ put the curly brace on the same line. Sure, you could
try to remember the ASI rules, but you're guaranteed to be safe if you just
put your braces on the same line. And considering how much code a typical
programmer writes, you are almost guaranteed to inflict an ASI bug on yourself
if you don't do this.

~~~
mc808
AFAIK, return statements are literally the only place where brace style is
affected by ASI.

    
    
        var result =
        {
            key: "value"
        };
    
        return result;
    

works fine, plus it lets you more easily break on the return statement and
verify/modify what will be returned when debugging. It would be kind of
awkward to see braces like that in JavaScript, but a style guide could just
ban returning object literals and make the ASI issue moot (at least regarding
braces; you still have the other gotchas with forgetting a comma in a variable
declaration, etc).

~~~
Roboprog
God I hate the term "semicolon insertion". It's a line oriented language, like
shell or BASIC. You only need semicolons when you put multiple statements on a
line (like a minifier does). Alas, like Ruby, JS does not require, or allow,
an explicit line continuation, such as a backslash or ampersand.

I hate the asshole at Netscape who decided the browser scripting language had
to be modeled after Java (C/C++, in other words), especially when it was
clearly meant to be a functional programming language that worked with lists
and property lists.

Man, I'm feeling "troll-ish" tonight. Not that I'm lying, just being blunt.

------
joeblow99
Use const for all of your references; avoid using var. If you must mutate
references, use let instead of var.

In my 15 years of programming javascript I've never once seen this matter.

~~~
RoboSeldon
That's because _let_ and _const_ where officially introduced in JavaScript
this year, see the JavaScript standard ES6 (or ES2015).

