JavaScript Style Guides And Beautifiers
May 3, 2012
Today we're going to explore JavaScript style guides, specifically: their importance, style guides worth reviewing and tools that can assist in automated code beautification or style enforcement.
What exactly is a style guide?
Before we begin, let us remind ourselves exactly what a code style guide is:
A style guide or style manual is a set of standards for the writing and design of code. The implementation of a style guide provides uniformity in code style and formatting, often covering guidelines regarding indentation (tabs vs. spaces), variable and function naming conventions, where best to apply whitespace and so on.
Why is consistent code style important?
They say that good code is it's own documentation. Whilst I don't completely agree with this (docs are important!), the fact is, the more readable our source code is, the easier it is to maintain.
Following a consistent style guide both helps enforce this concept and improves the overall quality of the code we write. This facilitates other developers stepping in to assist with maintenance more easily and can certainly save time in the long haul.
Readable source code is arguably easier for us to understand as well. It's easier to browse, locate and fix bugs in and more easy to optimize. It can also give us a clearer picture of how the code fits into a larger body of work. This is not to say that poorly styled code is badly written code. Indeed, I've seen several cases of code which were styled quite poorly, but were in fact, very efficiently written solutions on the whole.
Consistently styled code can:
- Reduce the lead time required to understand an implementation
- Make it easier to establish what code can be reused
- Clarify how updates to an implementation should be styled or structured (remember that consistent code, even when written by a team, should look like one person wrote it).
Are developers really using style guides in practice?
Advocating for the use of style guides is great, but it doesn't mean a great deal if only 1% of developers are seriously considering using them. To get a better gauge on this, I did an informal survey on Twitter, asking developers whether they were using a style guide for the JavaScript they were writing.
I received a relatively good sampling responses, below of which are a few:
- Rodney: Pretty much the jQuery style guide - just without the insane amount of whitespace
- Sindre: Idiomatic.js of course, with single-quotes and tab indention
- D.Cherman: There's no precedent in my group, but I'm pushing towards following the guidelines in idiomatic.js
- Marek: I use Crockford's style all the time, unless I'm contributing to a project that doesn't
- Jack: I use my own JS style guide, which essentially is a mash up of all the popular ones out there, very similar to them too
- Matt: Yes (based on jQuery and Idiomatic) but so long as projects are consistent then I'm flexible
- Jamie: I'd use an existing one in a team I was joining, or propose we agree on a standard if 1 wasn't in place. Happy with any style at all, just as long as there is one - so it reads like one person wrote it all. Just my opinion.
- Arthifiji: At work we are planning to use coding and style guides from Google. We have found it to be very comprehensive
Recommended JavaScript Style Guides
For developers interested in improving the code style consistency of the JavaScript they write, I'm happy to recommend the following style guides:
-
Idiomatic.js. This is not only highly recommended and very comprehensive, but is also the style guide we've adopted for several of the projects I'm involved in. It includes contributions by jQuery core contributor Rick Waldron, jsPerf contributor Mathias Bynens and many other experienced JS devs in the community. Not all developers agree 100% with the practices it advocates, but that's the great thing about a forkable style guide - it's easy to adapt to your own needs.
-
jQuery Core Style Guide. Perhaps the most popular style guide modern JS developers are aware of, it is used by the jQuery core team, jQuery UI, QUnit and many other projects. Rick Waldron once again had a hand in this as have Adam Sontag and John Resig, also of jQuery fame.
-
Google JavaScript Style Guide. Written by former Google JavaScript developers such as Robby Walker (Closure Linter), this contains several readability best practices that those from a particularly traditional software engineering background will appreciate. Further comments on it can be found here.
-
Dojo Style Guide Another very comprehensive alternative by the people that brought us the excellent dojo toolkit. Interestingly this guide is based on the structure of the Java programming conventions guide. If you like what you see, you might also appreciate dojo's inline documentation sguide, which remains my favorite style of inline commenting in JS.
-
Aloha Editor JavaScript Style Guide This guide comes from the authors of the relatively non-trivial contentEditable-based Aloha Editor. Whilst it recommends the jQuery style guide, it has some useful (minor) additions such as how they suggest styling AMD modules.
-
Crock's Code Conventions For JavaScript Another good guide, although perhaps not as detailed example-wise as others. I feel this has been superseded by Idiomatic.js, but if you strongly disagree with it or the jQuery core style guide, this is a much recommended fallback.
As two developers mentioned using the NPM style guide for their projects, I'll mention it in passing. Designed with reducing visual clutter in mind, this minimalist guide does contain similar practices to those seen in other guides above but is probably what I would consider a 'light' set of guidelines. The recommendations in 1-6 should definitely be considered more comprehensive.
Note: I've reviewed all of the above and discarded some other guides that were either entirely too brief/vague or (in my opinion) not that useful at all (e.g the GitHub JavaScript style guide).
A Tutorial On Applying The Principles Of Idiomatic Code Style
Let's go through a brief tutorial. Here is a functional block of code that doesn't follow any particular guidelines on code style:
function foo(bar,baz,fum){ var hello = "Hello"; var ret; var num = 1; for(var i = 0; i < bar.length; i++) { var out = bar[i]; if (out === ""){ ret = fum(out) + baz(out); } } if (!(ret == undefined)) { return ret; } else{ return fum('g2g'); } }
There's technically nothing wrong with it that would prevent it from running, but it could certainly be improved.
In order to better appreciate the impact of a consistently readable code style, let's go through this sample line-by-line and compare how it would look if we were to apply the Idiomatic.js style guide to it.
We will compare what the code looks like before and after it's been stylized and I've added notes in case it isn't clear on first glance.
1.Named function declarations
Before:
function foo(bar,fum,baz){
After:
function foo( bar, fum, baz ) {
What changed? We improved readability by:
- Forcing consistent spacing before each of the arguments
- Ensursing this accounts for a space after the function's opening bracket and before the closing bracket
- Adding a space between the closing bracket and the opening brace of the next block
2.Variable assignments
Before:
var hello = "Hello"; var ret; var num = 1;
And we also had inline variables in our for loop:
for(var i = 0; i < bar.length; i++) { var out = bar[i];
After:
var ret, out, hello = "Hello", num = 1, i = 0, l = bar.length;
What changed?
- We moved to using one 'var' per functional scope to promote readability. As the Idiomatic guide states, this allows our declaration list to be more free of clutter
- We moved the inline 'var' declaration for
i
from inside our loop to this same list.bar.length
was cached in this same list under a variablel
to avoid having to recalculate the length ofbar
each time. - We moved the 'var' declaration for
out
to this list. This follows the idea of only declaring newvar
s once in our scope
3.Loops:
Before:
for(var i = 0; i < bar.length; i++) {
After:
for ( ; i < l; i++ ) { out = bar[i];
What changed?
- Consistent whitespace is now used throughout the loop definition
- Specifically this is done (i) after the
for
keyword and prior to the opening bracket, (ii) between each expression/statement within the loop and (iii) prior to our opening brace - By setting our pointer
i
to0
prior to the loop, we can avoid the need to define this inline.Instead a simple semi-colon can be used in it's place, which some developers argue reduces clutter. Note: Hoisting the counter declaration to the top of the function is only a stylistic choice here and can be avoided if you feel uncomfortable with it. I personally would usually keep it inline to avoid detracting meaning.
4.Conditional evaluation:
Before:
if (out == ""){ ret = fum(out) + baz(out); }
After:
if ( !out ) { ret = fum( out ) + baz( out ); }
What changed?
- Rather than evaluating
out
is empty, we can instead evaluate falsy-ness instead (i.e!out
). This both requires fewer keystrokes and is arguably more readable - As in previous examples, liberal whitespace is used to surround arguments being passed to functions as this is easier on the eyes
5. Practicality - More on conditional evaluation
Before:
if (!(ret == undefined)) { return ret; } else{ return fum('g2g'); }
After:
return ret || fum('g2g');
What changed?
- We're no longer relying on the less reliable
==
(which should really have been===
anyway) !(ret == undefined)
could be rewritten as!(ret)
to once again, take advantage of falsy-ness (but this can be further improved)- Rather than opting for any of the verbose options above, we can take advantage of the fact that in an or expression,
ret
(ifundefined
orfalse
) will skip to the next condition and use it instead. This allows us to trim down our 5 lines of code into fewer characters and it's once again, a lot more readable
Our final product:
function foo( bar, baz, fum ) { var ret, out, hello = "Hello", num = 1, i = 0, l = bar.length; for ( ; i < l; i++ ) { out = bar[ i ]; if ( !out ) { ret = fum( out ) + baz( out ); } } return ret || fum('g2g'); }
Note: I'm aware there is much more that can be done to improve the original code sample. A proper solution would include type checking against bar
, baz
and fum
(and more), however for tutorial purposes, I wanted to focus on styling the core concepts.
Recommended JavaScript Beautifiers
Whilst maintaining consistent style while writing your code is extremely important, it can also be useful to use a formatter or beautifier to enforce style rules for you.
Google Closure Linter
Malte Ubl recently suggested that I try out Google Closure Linter. This set of useful Python scripts first allow us to lint our JavaScript against the Google JavaScript Style Guide, outputting a list of syntax and semantic changes needed to make our code Style-guide compatible. Users of tools like jsLint and jsHint will find following the output quite similar to what other linting tools report (line by line errors with the breaking issue reported) making it quite straight-forward to adjust our code accordingly.
The Closure Linter doesnt just lint code, however. It also includes a script called fixjsstyle which allows us to force (or beautify if you prefer) our code to follow Google's Style Guide.
Now, it is possible to use both the linter and beautifier scripts independently, but as a Sublime Text user, I would love to be able to simply use some keyboard shortcuts to lint or beautify my code using Closure Linter as I write it. Thankfully, someone already thought of this and theres a handy Sublime package available that does just this.
-
To install: Add this repository to Package Control: https://github.com/fbzhong/sublime-closure-linter and install.
-
Restart Sublime Text
-
You should now be able to lint or beautify your code using the following shortcuts:
- Run/Execute Closure Linter
ctrl+shift+j
- Fix JavaScript Style
ctrl+alt+shift+j
- Show Closure Linter Results in the console
Note: If you experience issues with paths to the linter tools not being correct, make sure that they have been correctly installed to /usr/bin. They may have been pulled into /local/usr/bin instead and you may need to either create a symbolic link to them or copy the files over to where the package is attempting to access them from.
- Run/Execute Closure Linter
jsBeautifier
jsBeautifier is another useful tool which you've most likely heard of before if not currently using at the moment. It accepts everything from poorly formatted JavaScript to fully minified code, applying a number of spacing/break best practices for making the code more readable. Its been possible to just use jsBeautifier from the terminal (and the popular jsbeautifier.org website) since it was first released, but similar to Googles Closure Linter, it would be incredibly helpful to have this available from directly within our text editor.
Luckily, there is also a Sublime Text package for jsBeautifier which can be downloaded from here. Installation just takes a minute.
- Extract and copy the package to your Sublime packages folder (the relevant path will be the same as the first step in the Closure Linter instructions above)
- Restart Sublime Text
- You can now beautify your code using
ctrl+alt+f
Note: You may also be interested in jsFormat - another JavaScript formatting plugin for Sublime which similarly uses jsBeautifier. It's also available on Package Control and should show up in your install list with no changes.
Code Painter
Whilst the above two beautification tools are helpful for improving readability, what developers really need is a solution thats more flexible.
We might not fully agree with the style guide choices enforced by Google Closure Linter or jsBeautifier. What if we would rather our code followed Rick Waldrons Idiomatic.js style guide? or the Dojo style guide? or something more custom?. It doesnt really make a great deal of sense to create new tools for supporting beautification of each individual type of style guide but thankfully there's a tool we can use to solve this problem.
It's a node.js based solution called Code Painter and it allows us to specify a sample JavaScript file following whatever style guide we wish as input, along with the code we would like beautified. Code Painter will infer the style rules to follow based on the sample and then transform our input as necessary.
From Jakub Wieczorek, the developer:
Code Painter is useful when you're working on a code change to a project and you want to make sure your new code fits its style. This could also be integrated with an editor so that it reformats your code as you type based on the style you've been using so far in a particular file. The solution is essentially a pipeline that consists of a tokenizer based on Esprima (with a few modifications to preserve comments and whitespaces), then a bunch of different style processors in the middle (one for each style property) and ends with a serializer that turns the token stream back into source code (this is a completely lossless process).
At the moment Code Painter only supports transformation of about 7 aspects of code style, but this may be enough for your needs. It shouldn't take long to see if it's able to handle the specific style rules you would like your project to enforce, so do check it out!
Code Painter can be grabbed from here and used as follows (assuming you already have Node):
./bin/codepaint -i myApp.js -s styleSample.js -o myAppStyled.js
Conclusions & Further Tips
- Maintaining a consistent formatting style for your code has a number of advantages, whether you opt to use someone else's style guide or your own. Many developers have found it useful to create a personal style guide with what they consider the 'best bits' of numerous others.
- Make effective use of whitespace to aid the readability of what you write.
- Use short, meaningful names for variables, functions and modules. This can help reduce the need for detailed inline comments if it means a developer can instantly grasp the purpose of a piece of code.
- Avoid code that is repetitive or can be rewritten to be shorter or more readable. This doesn't necessarily mean forcing everything to use the ternary operator or an or condition as we saw in our example. It is perfectly fine to keep code in an extended form, as long as it is easy to follow
- Where possible, maintain the principles 'You are not going to need it' (YAGNI) and Keep it short and simple (KISS) when coding. These again can help lower verbosity and improve how easy it can be to read what you're written.
That's it. I hope this guide is at least a little useful to someone out there : )
I'm always eager to hear about other takes on this topic or other published style guides. If you would like to contribute to the discussion, feel free to leave a comment or hit me up on Twitter. Cheers!
Many thanks to Sindre Sorhus for his technical review of this post and many useful suggestions that helped improve it.