Skip to content

Javascript Double Pipe Assignment Definition


Writing a best practice article is quite a tricky business. To a number of you, what you are about to read will appear to be very obvious and just the sensible thing to do.

However, looking around the web and getting code handed over to me from other developers for years has taught me that common sense is actually quite a rarity in live code on the web, and the “sensible and logical thing to do” gets pushed far down the priority list once you are in the middle of a project, and the deadline is looming.

So I’ve decided to make it easier for you by creating this article, which is a compilation of best practices and good advice I’ve amassed over the years, much of it learnt the hard way (experimentation and suchlike). Take the advice below to heart and keep it in a part of your brain that has a quick access route so you can apply it without thinking about it. I am sure you will find things to disagree with, and that is a good thing - you should question what you read, and strive to find better solutions. However, I have found that following these principles has made me a more effective developer and allowed other developers to build upon my work more easily.

Call things by their name — easy, short and readable variable and function names

This is a no-brainer but it is scary how often you will come across variables like , or in JavaScript, or — on the other end of the spectrum — variable names like or .

None of these make much sense — good variable and function names should be easy to understand and tell you what is going on — not more and not less. One trap to avoid is marrying values and functionality in names. A function called makes more sense than as the legal drinking age varies from country to country, and there are other things than drinking to consider that are limited by age.

Hungarian notation is a good variable naming scheme to adopt (there are other naming schemes to consider), the advantage being that you know what something is supposed to be and not just what it is.

For example, if you have a variable called and it is supposed to be a string, you would write it as in “Hungarian”. An object called would be and a Boolean called would be . It is very informative for some, but seems like extra overhead to others — it is really up to you whether you use it or not.

Keeping to English is a good idea, too. Programming languages are in English, so why not keep this as a logical step for the rest of your code. Having spent some time debugging Korean and Slovenian code, I can assure you it is not much fun for a non-native speaker.

See your code as a narrative. If you can read line by line and understand what is going on, well done. If you need to use a sketchpad to keep up with the flow of logic, then your code needs some work. Try reading Dostojewski if you want a comparison to the real world — I got lost on a page with 14 Russian names, 4 of which were pseudonyms. Don't write code like that — it might make it more art than product, but this is rarely a good thing.

Avoid globals

Global variables and function names are an incredibly bad idea. The reason is that every JavaScript file included in the page runs in the same scope. If you have global variables or functions in your code, scripts included after yours that contain the same variable and function names will overwrite your variables/functions.

There are several workarounds to avoid using globals — we’ll go through them one by one now. Say you have three functions and a variable like this:

var current = null; function init(){...} function change(){...} function verify(){...}

You can protect those from being overwritten by using an object literal:

This does the job, but there is a drawback — to call the functions or change the variable value you’ll always need to go via the name of the main object: is , current is and so on. This can get annoying and repetitive.

It is easier to wrap the whole thing in an anonymous function and protect the scope that way. That also means you don’t have to switch syntax from to . This trick is called the Module Pattern:

Again, this approach is not without issues. None of these are available from the outside at all any more. If you want to make them available you need to wrap the things you want to make public in a statement:

That pretty much brings us back to square one in terms of linking from one to the other and changing syntax. I therefore prefer to do something like the following (which I dubbed the “revealing module pattern”):

Instead of returning the properties and methods I just return pointers to them. This makes it easy to call functions and access variables from other places without having to go through the name.

It also means that you can have a public alias for a function in case you want to give it a longer, descriptive name for internal linking but a shorter one for the outside:

Calling will now invoke the method.

If you don’t need any of your variables or functions to be available to the outside, simply wrap the whole construct in another set of parentheses to execute it without assigning any name to it:

This keeps everything in a tidy little package that is inaccessible to the outside world, but very easy to share variables and functions inside of.

Stick to a strict coding style

Browsers are very forgiving when it comes to JavaScript syntax. This should not however be a reason for you to write sloppy code that relies on browsers to make it work.

The easiest way to check the syntactical quality of your code is to run it through JSLint — a JavaScript validation tool that gives you a detailed report about the syntax warnings and their meaning. People have been writing extensions for editors (for example the JS Tools for TextMate) that automatically lint your code when you save it.

JSLint can be a bit touchy about the results it returns and — as its developer Douglas Crockford says — it can hurt your feelings. I found myself write much better code however, since I installed the TextMate JS bundle and started subjecting my code to JSLint scrutiny.

Clean and valid code means less confusing bugs to fix, easier handover to other developers and better code security. When you rely on hacks to get your code to work it is likely that there is also a security exploit that uses the same hacks. In addition, as hacks get fixed in browsers, your code will cease to work in the next version of the browser.

Valid code also means that it can be converted by scripts to other formats — hacky code will need a human to do that.

Comments are your messages to other developers (and yourself, if you come back to your code after several months working on something else). There’s been numerous battles raging over the years about whether to use comments at all, the main argument being that good code should explain itself.

What I see as a flaw in this argument is that explanations are a very subjective thing — you cannot expect every developer to understand what some code is doing from exactly the same explanation.

Comments don’t hurt anybody if you do them right. We’ll come back to that in the last point of this article, but let’s say that if your comments end up in the code that end users see then something is not going right.

Again the trick is moderation. Comment when there is an important thing to say, and if you do comment use the notation. Single line comments using can be problematic if people minify your code without stripping comments and in general are less versatile.

If you comment out parts of your code to be used at a later stage or to debug code there is a pretty sweet trick you can do:

Adding a double slash before the closing star-slash sets your code up so that you can comment and uncomment the whole block by simply adding or removing a slash before the opening slash-star:

With the code set up as shown in the above block, adding a slash before the opening slash-star will turn the multiline comment into two one-line comments, “unhiding” the code in between and causing it to be executed. Removing the slash will comment it out again.

For larger applications comment documentation in JavaDoc style makes a lot of sense — you are seeding the overall documentation of your product by writing code. The Yahoo User Interface library's success is partly attributable to this, and there is even a tool you can use to build the same documentation for your products. Don’t worry too much about this until you become more experienced with JavaScripting — JavaDoc is mentioned here for completeness.

Avoid mixing with other technologies

Whilst it is possible to create everything you need in a document using JavaScript and the DOM it is not necessarily the most effective way of doing so. The following code puts a red border around every input field when its class is “mandatory” and there’s nothing in it.

var f = document.getElementById('mainform'); var inputs = f.getElementsByTagName('input'); for(var i=0,j=inputs.length;i<j;i++){ if(inputs[i].className === 'mandatory' && inputs[i].value === ''){ inputs[i].style.borderColor = '#f00'; inputs[i].style.borderStyle = 'solid'; inputs[i].style.borderWidth = '1px'; } }

This works, however it means that if you later need to make a change to these styles you need to go through the JavaScript and apply the changes there. The more complex the change is the harder it’ll be to edit this. Furthermore, not every JavaScript developer is proficient or interested in CSS, which means there will be a lot of back and forth until the outcome is reached. By adding a class called “error” to the element when there is an error, you can ensure that the styling information is kept inside the CSS, which is more appropriate:

var f = document.getElementById('mainform'); var inputs = f.getElementsByTagName('input'); for(var i=0,j=inputs.length;i<j;i++){ if(inputs[i].className === 'mandatory' && inputs[i].value === ''){ inputs[i].className += ' error'; } }

This is much more efficient as CSS was meant to cascade through the document. Say for example you want to hide all DIVs with a certain class in a document. You could loop through all the DIVs, check their classes and then change their style collection. In newer browsers you could use a CSS selector engine and then alter the style collection. The easiest way however is to use JavaScript to set a class on a parent element and use syntax along the lines of in the CSS. Keep the job of actually hiding the DIVs to the CSS designer, as he’ll know the best way of doing that.

Use shortcut notation when it makes sense

Shortcut notation is a tricky subject: on the one hand it keeps your code small but on the other you might make it hard for developers that take over from you as they might not be aware of the shortcuts. Well, here’s a small list of what can (and should) be done.

Objects are probably the most versatile thing you have in JavaScript. The old-school way of writing them is doing something like this:

However, this means you need to repeat the object name for each property or method, which can be annoying. Instead it makes much more sense to have the following construct, also called an object literal:

Arrays are a confusing point in JavaScript. You’ll find a lot of scripts defining an Array in the following way:

var awesomeBands = new Array(); awesomeBands[0] = 'Bad Religion'; awesomeBands[1] = 'Dropkick Murphys'; awesomeBands[2] = 'Flogging Molly'; awesomeBands[3] = 'Red Hot Chili Peppers'; awesomeBands[4] = 'Pornophonique';

This is a lot of useless repetition; this can be written a lot more quickly using the array shortcut:

var awesomeBands = [ 'Bad Religion', 'Dropkick Murphys', 'Flogging Molly', 'Red Hot Chili Peppers', 'Pornophonique' ];

You will come across the term “associative array” in some tutorials. This is a misnomer as arrays with named properties rather than an index are actually objects and should be defined as such.

Conditions can be shortened using “ternary notation”. For example, the following construct defines a variable as 1 or -1, depending on the value of another variable:

var direction; if(x > 100){ direction = 1; } else { direction = -1; }

This can be shortened to a single line:

var direction = (x > 100) ? 1 : -1;

Anything before the question mark is the condition, the value immediately after it is the true case and the one after the colon the false case. Ternary notation can be nested, but I’d avoid that to keep things readable.

Another common situation in JavaScript is providing a preset value for a variable if it is not defined, like so:

if(v){ var x = v; } else { var x = 10; }

The shortcut notation for this is the double pipe character:

var x = v || 10;

This will automatically give a value of if is not defined — simple as that.

Modularize — one function per task

This is a general programming best practice — making sure that you create functions that fulfill one job at a time makes it easy for other developers to debug and change your code without having to scan through all the code to work out what code block performs what function.

This also applies to creating helper functions for common tasks. If you find yourself doing the same thing in several different functions then it is a good idea to create a more generic helper function instead, and reuse that functionality where it is needed.

Also, one way in and one way out makes more sense than forking the code in the function itself. Say you wanted to write a helper function to create new links. You could do it like this:

function addLink(text,url,parentElement){ var newLink = document.createElement('a'); newLink.setAttribute('href',url); newLink.appendChild(document.createTextNode(text)); parentElement.appendChild(newLink); }

This works ok, but you might find yourself having to add different attributes depending on which elements you apply the link to. For example:

function addLink(text,url,parentElement){ var newLink = document.createElement('a'); newLink.setAttribute('href',url); newLink.appendChild(document.createTextNode(text)); if( === 'menu'){ newLink.className = 'menu-item'; } if(url.indexOf('mailto:')!==-1){ newLink.className = 'mail'; } parentElement.appendChild(newLink); }

This makes the function more specific and harder to apply to different situations. A cleaner way is to return the link and cover the extra cases in the main functions that need them. This turns into the more generic :

function createLink(text,url){ var newLink = document.createElement('a'); newLink.setAttribute('href',url); newLink.appendChild(document.createTextNode(text)); return newLink; } function createMenu(){ var menu = document.getElementById('menu'); var items = [ {t:'Home',u:'index.html'}, {t:'Sales',u:'sales.html'}, {t:'Contact',u:'contact.html'} ]; for(var i=0;i<items.length;i++){ var item = createLink(items.t,items.u); item.className = 'menu-item'; menu.appendChild(item); } }

By having all your functions only perform one task you can have a main function for your application that contains all the application structure. That way you can easily change the application and remove functionality without having to scan the rest of the document for dependencies.

Enhance progressively

Progressive Enhancement as a development practice is discussed in detail in the Graceful degradation versus progressive enhancement. In essence what you should do is write code that works regardless of available technology. In the case of JavaScript, this means that when scripting is not available (say on a BlackBerry, or because of an over-zealous security policy) your web products should still allow users to reach a certain goal, not block them because of the lack of JavaScript which they can’t turn on, or don’t want to.

It is amazing how many times you will build a massively convoluted JavaScript solution for a problem that can be solved easily without it. One example I encountered was a search box on a page that allowed you to search different data: the web, images, news and so on.

In the original version the different data options were links that would re-write the attribute of the form to point to different scripts on the back end to perform the searches.

The problem was that if JavaScript was turned off the links would still show up but every search would return standard web results as the action of the form never got changed. The solution was very simple: instead of links we provided the options as a radio button group and did the forking to the different specialist search scripts using a back end script.

This not only made the search work correctly for everybody, it also made it easy to track how many users chose which option. By using the correct HTML construct we managed to get rid of both the JavaScript to switch the form action and the click tracking scripts and made it work for every user out there — regardless of environment.

Allow for configuration and translation

One of the most successful tips to keep your code maintainable and clean is to create a configuration object that contains all the things that are likely to change over time. These include any text used in elements you create (including button values and alternative text for images), CSS class and ID names and general parameters of the interface you build.

For example the Easy YouTube player has the following configuration object:

/* This is the configuration of the player. Most likely you will never have to change anything here, but it is good to be able to, isn't it? */ config = { CSS:{ /* IDs used in the document. The script will get access to the different elements of the player with these IDs, so if you change them in the HTML below, make sure to also change the name here! */ IDs:{ container:'eytp-maincontainer', canvas:'eytp-playercanvas', player:'eytp-player', controls:'eytp-controls', volumeField:'eytp-volume', volumeBar:'eytp-volumebar', playerForm:'eytp-playerform', urlField:'eytp-url', sizeControl:'eytp-sizecontrol', searchField:'eytp-searchfield', searchForm:'eytp-search', searchOutput:'eytp-searchoutput' /* Notice there should never be a comma after the last entry in the list as otherwise MSIE will throw a fit! */ }, /* These are the names of the CSS classes, the player adds dynamically to the volume bar in certain situations. */ classes:{ maxvolume:'maxed', disabled:'disabled' /* Notice there should never be a comma after the last entry in the list as otherwise MSIE will throw a fit! */ } }, /* That is the end of the CSS definitions, from here on you can change settings of the player itself. */ application:{ /* The YouTube API base URL. This changed during development of this, so I thought it useful to make it a parameter. */ youtubeAPI:'', /* The YouTube Developer key, please replace this with your own when you host the player!!!!! */ devkey:'AI39si7d...Y9fu_cQ', /* The volume increase/decrease in percent and the volume message shown in a hidden form field (for screen readers). The $x in the message will be replaced with the real value. */ volumeChange:10, volumeMessage:'volume $x percent', /* Amount of search results and the error message should there be no results. */ searchResults:6, loadingMessage:'Searching, please wait', noVideosFoundMessage:'No videos found : (', /* Amount of seconds to repeat when the user hits the rewind button. */ secondsToRepeat:10, /* Movie dimensions. */ movieWidth:400, movieHeight:300 /* Notice there should never be a comma after the last entry in the list as otherwise MSIE will throw a fit! */ } }

If you have this as a part of a module pattern and make it public you even allow implementers to only override what they need before initializing your module.

It is of utmost importance to keep code maintenance simple, avoiding the need for future maintainers having to read all your code and find where they need to change things. If it isn’t obvious, your solution will be either completely ditched or hacked. Hacked solutions can’t be patched once you need to upgrade them and that kills re-use of code.

Avoid heavy nesting

Nesting code explains its logic and makes it much easier to read, however nesting it too far can also make it hard to follow what you are trying to do. Readers of your code shouldn’t have to scroll horizontally, or suffer confusion when their code editors wrap long lines (this makes your indentation efforts moot anyway).

The other problem of nesting is variable names and loops. As you normally start your first loop with as the iterator variable, you’ll go on with j,k,l and so on. This can become messy quite quickly:

function renderProfiles(o){ var out = document.getElementById(‘profiles’); for(var i=0;i<o.members.length;i++){ var ul = document.createElement(‘ul’); var li = document.createElement(‘li’); li.appendChild(document.createTextNode(o.members[i].name)); var nestedul = document.createElement(‘ul’); for(var j=0;j<o.members[i].data.length;j++){ var datali = document.createElement(‘li’); datali.appendChild( document.createTextNode( o.members[i].data[j].label + ‘ ‘ + o.members[i].data[j].value ) ); nestedul.appendChild(datali); } li.appendChild(nestedul); } out.appendChild(ul); }

As I am using the generic — really throw-away — variable names and here, I need and for the nested list items. If the list nesting were to go even deeper I would need more variable names, and so on and so on. It makes more sense to put the task of creating nested lists for each member in its own function and call this with the right data. This also prevents us from having a loop inside a loop. The function is pretty generic and is very likely to come in handy at another time. Taking these thoughts on board, I would rewrite the code as follows:

function renderProfiles(o){ var out = document.getElementById(‘profiles’); for(var i=0;i<o.members.length;i++){ var ul = document.createElement(‘ul’); var li = document.createElement(‘li’); li.appendChild(document.createTextNode(data.members[i].name)); li.appendChild(addMemberData(o.members[i])); } out.appendChild(ul); } function addMemberData(member){ var ul = document.createElement(‘ul’); for(var i=0;i<;i++){ var li = document.createElement(‘li’); li.appendChild( document.createTextNode([i].label + ‘ ‘ +[i].value ) ); } ul.appendChild(li); return ul; }

Optimize loops

Loops can become very slow if you don’t do them right. One of the most common mistake is to read the length attribute of an array at every iteration:

var names = ['George','Ringo','Paul','John']; for(var i=0;i<names.length;i++){ doSomeThingWith(names[i]); }

This means that every time the loop runs, JavaScript needs to read the length of the array. You can avoid that by storing the length value in a different variable:

var names = ['George','Ringo','Paul','John']; var all = names.length; for(var i=0;i<all;i++){ doSomeThingWith(names[i]); }

An even shorter way of achieving this is to create a second variable in the pre-loop statement:

var names = ['George','Ringo','Paul','John']; for(var i=0,j=names.length;i<j;i++){ doSomeThingWith(names[i]); }

Another thing to ensure is that you keep computation-heavy code outside loops. This includes regular expressions and — more importantly — DOM manipulation. You can create the DOM nodes in the loop but avoid inserting them into the document. You’ll find more on DOM best practices in the next section.

Keep DOM access to a minimum

Accessing the DOM in browsers is an expensive thing to do. The DOM is a very complex API and rendering in browsers can take up a lot of time. You can see this when running complex web applications when your computer is already maxed out with other work — changes take longer or get shown half way through and so on.

To make sure that your code is fast and doesn’t slow down the browser to a halt try to keep DOM access to a bare minimum. Instead of constantly creating and applying elements, have a tool function that turns a string into DOM elements and call this function at the end of your generation process to disturb the browser rendering once rather than continually.

Don’t yield to browser whims

Writing code specific to a certain browser is a sure-fire way to keep your code hard to maintain and make it get dated really quickly. If you look around the web you’ll find a lot of scripts that expect a certain browser and stop working as soon as a new version or another browser comes around.

This is wasted time and effort — we should build code based on agreed standards as outlined in this course of articles, not for one browser. The web is for everybody, not an elite group of users with a state-of-the-art configuration. As the browser market moves quickly you will have to go back to your code and keep fixing it. This is neither effective nor fun.

If something amazing works in one browser only and you really have to use it, put that code in its own script document and name it with browser and version. This means that you can find and remove this functionality more easily, should this browser become obsolete.

Don’t trust any data

One of the main points to bear in mind when talking about code and data security is not to trust any data. This is not only about evil people wanting to hack your systems; it starts with plain usability. Users will enter incorrect data, all the time. Not because they are stupid, but because they are busy, distracted or the wording on your instructions is confusing them. For example, I just booked a hotel room for a month rather than six days as I entered a wrong number … I consider myself fairly smart.

In short, make sure that all the data that goes into your systems is clean and exactly what you need. This is most important on the back end when writing out parameters retrieved from the URL. In JavaScript, it is very important to test the type of parameters sent to your functions (using the keyword). The following would be an error if is not an Array (for example for a string it’ll create a list item for each character of the string):

function buildMemberList(members){ var all = members.length; var ul = document.createElement('ul'); for(var i=0;i<all;i++){ var li = document.createElement('li'); li.appendChild(document.createTextNode(members[i].name)); ul.appendChild(li); } return ul; }

In order to make this work, you need to check the type of and make sure it is an array:

function buildMemberList(members){ if(typeof members === 'object' && typeof members.slice === 'function'){ var all = members.length; var ul = document.createElement('ul'); for(var i=0;i<all;i++){ var li = document.createElement('li'); li.appendChild(document.createTextNode(members[i].name)); ul.appendChild(li); } return ul; } }

Arrays are tricky as they tell you they are objects. To ensure that they are arrays, check one of the methods only arrays have.

Another very insecure practice is to read information from the DOM and use it without comparison. For example, I once had to debug some code that caused the JavaScript functionality to break. The code that caused it was — for some reason beyond me — reading a user name out of the innerHTML from a page element and calling a function with the data as a parameter. As the user name could be any UTF-8 character this included quotation marks and single quotes. These would end any string and the remaining part would be erroneous data. In addition, any user changing the HTML using a tool like Firebug or Opera DragonFly could change the user name to anything and inject this data into your functions.

The same applies to forms that validate only on the client side. I once signed up for an unavailable email address by rewriting a select to provide another option. As the form wasn’t checked on the back end the process went through without a hitch.

For DOM access, check that the element you try to reach and alter is really available and what you expect it to be — otherwise your code may fail or cause strange rendering bugs.

Add functionality with JavaScript, don’t create too much content

As you can see in some of the other examples here, building a lot of HTML in JavaScript can be pretty daunting and flaky. Especially on Internet Explorer you can run into all kinds of trouble by altering the document while it is still loading and manipulating the content (look up “operation aborted error” on Google for a tale of woe and misery) with .

In terms of page maintenance it is also a terribly bad idea to create a lot of markup with HTML as not every maintainer will have the same level of skill as you have and could potentially really mess with your code.

I found that when I had to build an application that is very much dependent on JavaScript using an HTML template and loading this template via Ajax made much more sense. That way maintainers can alter the HTML structure and most importantly text without having to interfere with your JavaScript code. The only snag is to tell them which IDs are needed and if there are certain HTML constructs that need to be in the order you defined. You can do that with inline HTML comments (and then strip the comments out when you load the template. Check the source of the Easy YouTube template as an example.

In the script I load the template when the correct HTML container is available and apply the event handlers in the method afterwards:

This way I enable people to translate and change the player any way they want to without having to alter the JavaScript code.

Build on the shoulders of giants

There is no denying that over the last few years JavaScript libraries and frameworks have taken over the web development market. And that is not a bad thing — if they are used correctly. All good JavaScript libraries want to do one thing and one thing only: make your life as a developer easier by working around cross-browser inconsistencies and patching browser support holes. JavaScript libraries provide you with a predictable, functioning base line to build upon.

It’s a good idea to learn JavaScript without libraries first, so you really know what’s going on, but you should make use of a JS library when you start developing web sites. You’ll have less issues to deal with and at least the bugs that appear will be ones that can be reproduced — not random browser issues.

My personal favourite is the Yahoo User Interface library (YUI), followed by jQuery, Dojo and Prototype but there are dozens of other good libraries out there and you should find the one that suits you and your product best.

Whilst all libraries do work well together, it is not a good idea to use several libraries in the same project. This brings in another superfluous level of complexity and maintenance.

Development code is not live code

The last point I want to make is not about JavaScript itself but about how it fits into the rest of your development strategy. As any change in JavaScript has an immediate effect on the performance and functionality of your web applications it is very tempting to optimize your code as much as possible regardless of the consequences for maintenance.

There are a lot of clever tricks you can apply to JavaScript to make it perform great. Most of them come with the drawback of making your code hard to understand and maintain.

In order to write secure, working JavaScript we need to break this cycle and stop optimizing code for machines rather than other developers. Most — something that is very common in other languages but not as well known amongts JavaScripters. A build script can remove whitespace, comments, replace strings with Array lookups (to avoid MSIE creating a string object for every single instance of a string — even in conditions) and do all the other small tweaks needed to make our JavaScript fly in browsers.

If we concentrate more on making the initial code easy to understand and extend by other developers we can create the perfect build script. If we keep optimizing prematurely we’ll never get there. Do not build for yourself or the browser — build for the next developer who takes over from you.


The main trick with JavaScript is to avoid taking the easy path. JavaScript is a wonderfully versatile language and as the environment it is executed in is very forgiving it is easy to write sloppy code that seemingly does the job. This same code however will come back to bite you a few months down the line.

JavaScript development has mutated from a fringe knowledge area to an absolute necessity if you want to have a job as a web developer. If you are starting right now you are lucky, as myself and many others have already made most of the mistakes and done all the trial and error self-teaching; we can now pass that knowledge along.

Note: This material was previously published as part of the Opera Web Standards Curriculum, available as 42: JavaScript best practices, written by Christian Heilmann. Like the original, it is published under the Creative Commons Attribution, Non Commercial - Share Alike 2.5 license.

CoffeeScript is a little language that compiles into JavaScript. Underneath that awkward Java-esque patina, JavaScript has always had a gorgeous heart. CoffeeScript is an attempt to expose the good parts of JavaScript in a simple way.

The golden rule of CoffeeScript is: “It’s just JavaScript.” The code compiles one-to-one into the equivalent JS, and there is no interpretation at runtime. You can use any existing JavaScript library seamlessly from CoffeeScript (and vice-versa). The compiled output is readable, pretty-printed, and tends to run as fast or faster than the equivalent handwritten JavaScript.

Latest Version:2.2.2


CoffeeScript on the topleft, compiled JavaScript output on the bottomright. The CoffeeScript is editable!

number=42opposite=truenumber=-42ifoppositesquare=(x)->x*xlist=[1,2,3,4,5]math=root:Math.sqrtsquare:squarecube:(x)->x*squarexrace=(winner,runners...)->printwinner,runnersalert"I knew it!"ifelvis?cubes=(math.cubenumfornuminlist)
varcubes, list, math, num, number, opposite, race, square; number=42; opposite=true; if (opposite) { number=-42; } square=function(x) { returnx*x; }; list= [1, 2, 3, 4, 5]; math= { root: Math.sqrt, square: square, cube: function(x) { returnx*square(x); } }; race=function(winner, ...runners) { returnprint(winner, runners); }; if (typeofelvis!=="undefined"&&elvis!==null) { alert("I knew it!"); } cubes= (function() { vari, len, results; results= []; for (i=0, len=list.length; i<len; i++) { num=list[i]; results.push(math.cube(num)); } returnresults; })();


The command-line version of is available as a Node.js utility, requiring Node 6 or later. The core compiler however, does not depend on Node, and can be run in any JavaScript environment, or in the browser (see Try CoffeeScript).

To install, first make sure you have a working copy of the latest stable version of Node.js. You can then install CoffeeScript globally with npm:

This will make the and commands available globally.

If you are using CoffeeScript in a project, you should install it locally for that project so that the version of CoffeeScript is tracked as one of your project’s dependencies. Within that project’s folder:

The and commands will first look in the current folder to see if CoffeeScript is installed locally, and use that version if so. This allows different versions of CoffeeScript to be installed globally and locally.

If you plan to use the option (see Transpilation) you will need to also install either globally or locally, depending on whether you are running a globally or locally installed version of CoffeeScript.


Command Line

Once installed, you should have access to the command, which can execute scripts, compile files into , and provide an interactive REPL. The command takes the following options:

Compile a script into a JavaScript file of the same name.
Pipe the CoffeeScript compiler’s output through Babel before saving or running the generated JavaScript. Requires to be installed, and options to pass to Babel in a file or a with a key in the path of the file or folder to be compiled. See Transpilation.
Generate source maps alongside the compiled JavaScript files. Adds directives to the JavaScript as well.
Just like , but include the source map directly in the compiled JavaScript files, rather than in a separate file.
Launch an interactive CoffeeScript session to try short snippets. Identical to calling with no arguments.
Write out all compiled JavaScript files into the specified directory. Use in conjunction with or .
Watch files for changes, rerunning the specified command when any file is updated.
Instead of writing out the JavaScript as a file, print it directly to stdout.
Pipe in CoffeeScript to STDIN and get back JavaScript over STDOUT. Good for use with processes written in other languages. An example:
Parses the code as Literate CoffeeScript. You only need to specify this when passing in code directly over stdio, or using some sort of extension-less file name.
Compile and print a little snippet of CoffeeScript directly from the command line. For example:
the given module before starting the REPL or evaluating the code given with the flag.
Compile the JavaScript without the top-level function safety wrapper.
Suppress the “Generated by CoffeeScript” header.
The executable has some useful options you can set, such as , , , and . Use this flag to forward options directly to Node.js. To pass multiple flags, use multiple times.
Instead of parsing the CoffeeScript, just lex it, and print out the token stream. Used for debugging the compiler.
Instead of compiling the CoffeeScript, just lex and parse it, and print out the parse tree. Used for debugging the compiler.


  • Compile a directory tree of files in into a parallel tree of files in :
  • Watch a file for changes, and recompile it every time the file is saved:
  • Concatenate a list of files into a single script:
  • Print out the compiled JS from a one-liner:
  • All together now, watch and recompile an entire project as you work on it:
  • Start the CoffeeScript REPL ( to exit, for multi-line):

To use , see Transpilation.


If you’d like to use Node.js’ CommonJS to CoffeeScript files, e.g. , you must first “register” CoffeeScript as an extension:

If you want to use the compiler’s API, for example to make an app that compiles strings of CoffeeScript on the fly, you can the full module:

The method has the signature where is a string of CoffeeScript code, and the optional is an object with some or all of the following properties:

  • , boolean: if true, a source map will be generated; and instead of returning a string, will return an object of the form .
  • , boolean: if true, output the source map as a base64-encoded string in a comment at the bottom.
  • , string: the filename to use for the source map. It can include a path (relative or absolute).
  • , boolean: if true, output without the top-level function safety wrapper.
  • , boolean: if true, output the header.
  • , object: if set, this must be an object with the options to pass to Babel. See Transpilation.


CoffeeScript 2 generates JavaScript that uses the latest, modern syntax. The runtime or browsers where you want your code to run might not support all of that syntax. In that case, we want to convert modern JavaScript into older JavaScript that will run in older versions of Node or older browsers; for example, into . This is done via transpilers like Babel, Bublé or Traceur Compiler.


From the root of your project:

Transpiling with the CoffeeScript compiler

To make things easy, CoffeeScript has built-in support for the popular Babel transpiler. You can use it via the command-line option or the Node API option. To use either, must be installed in your project:

Or if you’re running the command outside of a project folder, using a globally-installed module, needs to be installed globally:

By default, Babel doesn’t do anything—it doesn’t make assumptions about what you want to transpile to. You need to provide it with a configuration so that it knows what to do. One way to do this is by creating a file in the folder containing the files you’re compiling, or in any parent folder up the path above those files. (Babel supports other ways, too.) A minimal file would be just . This implies that you have installed :

See Babel’s website to learn about presets and plugins and the multitude of options you have. Another preset you might need is if you’re using JSX with React (JSX can also be used with other frameworks).

Once you have and (or other presets or plugins) installed, and a file (or other equivalent) in place, you can use to pipe CoffeeScript’s output through Babel using the options you’ve saved.

If you’re using CoffeeScript via the Node API, where you call with a string to be compiled and an object, the key of the object should be the Babel options:

You can also transpile CoffeeScript’s output without using the option, for example as part of a build chain. This lets you use transpilers other than Babel, and it gives you greater control over the process. There are many great task runners for setting up JavaScript build chains, such as Gulp, Webpack, Grunt and Broccoli.


Note that transpiling doesn’t automatically supply polyfills for your code. CoffeeScript itself will output if you use the operator, or destructuring or spread/rest syntax; and if you use a bound () method in a class. Both are supported in Internet Explorer 9+ and all more recent browsers, but you will need to supply polyfills if you need to support Internet Explorer 8 or below and are using features that would cause these methods to be output. You’ll also need to supply polyfills if your own code uses these methods or another method added in recent versions of JavaScript. One polyfill option is , though there are many otherstrategies.

Language Reference

This reference is structured so that it can be read from top to bottom, if you like. Later sections use ideas and syntax previously introduced. Familiarity with JavaScript is assumed. In all of the following examples, the source CoffeeScript is provided on the left, and the direct compilation into JavaScript is on the right.

Many of the examples can be run (where it makes sense) by pressing thebutton on the right. The CoffeeScript on the left is editable, and the JavaScript will update as you edit.

First, the basics: CoffeeScript uses significant whitespace to delimit blocks of code. You don’t need to use semicolons to terminate expressions, ending the line will do just as well (although semicolons can still be used to fit multiple expressions onto a single line). Instead of using curly braces to surround blocks of code in functions, if-statements, switch, and try/catch, use indentation.

You don’t need to use parentheses to invoke a function if you’re passing arguments. The implicit call wraps forward to the end of the line or block expression.


Functions are defined by an optional list of parameters in parentheses, an arrow, and the function body. The empty function looks like this:

varcube, square; square=function(x) { returnx*x; }; cube=function(x) { returnsquare(x) *x; };

Functions may also have default values for arguments, which will be used if the incoming argument is missing ().

fill=(container,liquid="coffee")->"Filling the #{container} with #{liquid}..."
varfill; fill=function(container, liquid="coffee") { return`Filling the ${container}with ${liquid}...`; };


Like JavaScript and many other languages, CoffeeScript supports strings as delimited by the or characters. CoffeeScript also supports string interpolation within -quoted strings, using . Single-quoted strings are literal. You may even use interpolation in object keys.

author="Wittgenstein"quote="A picture is a fact. -- #{ author }"sentence="#{ 22 / 7 } is a decent approximation of π"
varauthor, quote, sentence; author="Wittgenstein"; quote=`A picture is a fact. -- ${author}`; sentence=`${22/7}is a decent approximation of π`;

Multiline strings are allowed in CoffeeScript. Lines are joined by a single space unless they end with a backslash. Indentation is ignored.

mobyDick="Call me Ishmael. Some years ago -- never mind how long precisely -- having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world..."
varmobyDick; mobyDick="Call me Ishmael. Some years ago -- never mind how long precisely -- having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world...";

Block strings, delimited by or , can be used to hold formatted or indentation-sensitive text (or, if you just don’t feel like escaping quotes and apostrophes). The indentation level that begins the block is maintained throughout, so you can keep it all aligned with the body of your code.

html=""" <strong> cup of coffeescript </strong> """
varhtml; html="<strong>\n cup of coffeescript\n</strong>";

Double-quoted block strings, like other double-quoted strings, allow interpolation.

Objects and Arrays

The CoffeeScript literals for objects and arrays look very similar to their JavaScript cousins. When each property is listed on its own line, the commas are optional. Objects may be created using indentation instead of explicit braces, similar to YAML.

varbitlist, kids, singers, song; song= ["do", "re", "mi", "fa", "so"]; singers= { Jagger: "Rock", Elvis: "Roll" }; bitlist= [1, 0, 1, 0, 0, 1, 1, 1, 0]; kids= { brother: { name: "Max", age: 11 }, sister: { name: "Ida", age: 9 } };

CoffeeScript has a shortcut for creating objects when you want the key to be set with a variable of the same name.

name="Michelangelo"mask="orange"weapon="nunchuks"turtle={name,mask,weapon}output="#{} wears an #{turtle.mask} mask. Watch out for his #{turtle.weapon}!"
varmask, name, output, turtle, weapon; name="Michelangelo"; mask="orange"; weapon="nunchuks"; turtle= {name, mask, weapon}; output=`${}wears an ${turtle.mask}mask. Watch out for his ${turtle.weapon}!`;

Lexical Scoping and Variable Safety

The CoffeeScript compiler takes care to make sure that all of your variables are properly declared within lexical scope — you never need to write yourself.

varchangeNumbers, inner, outer; outer=1; changeNumbers=function() { varinner; inner=-1; returnouter=10; }; inner=changeNumbers();

Notice how all of the variable declarations have been pushed up to the top of the closest scope, the first time they appear. is not redeclared within the inner function, because it’s already in scope; within the function, on the other hand, should not be able to change the value of the external variable of the same name, and therefore has a declaration of its own.

Because you don’t have direct access to the keyword, it’s impossible to shadow an outer variable on purpose, you may only refer to it. So be careful that you’re not reusing the name of an external variable accidentally, if you’re writing a deeply nested function.

Although suppressed within this documentation for clarity, all CoffeeScript output (except in files with or statements) is wrapped in an anonymous function: . This safety wrapper, combined with the automatic generation of the keyword, make it exceedingly difficult to pollute the global namespace by accident. (The safety wrapper can be disabled with the option, and is unnecessary and automatically disabled when using modules.)

If you’d like to create top-level variables for other scripts to use, attach them as properties on ; attach them as properties on the object in CommonJS; or use an statement. If you’re targeting both CommonJS and the browser, the existential operator (covered below), gives you a reliable way to figure out where to add them: .

Since CoffeeScript takes care of all variable declaration, it is not possible to declare variables with ES2015’s or . This is intentional; we feel that the simplicity gained by not having to think about variable declaration outweighs the benefit of having three separate ways to declare variables.

If, Else, Unless, and Conditional Assignment

/ statements can be written without the use of parentheses and curly brackets. As with functions and other block expressions, multi-line conditionals are delimited by indentation. There’s also a handy postfix form, with the or at the end.

CoffeeScript can compile statements into JavaScript expressions, using the ternary operator when possible, and closure wrapping otherwise. There is no explicit ternary statement in CoffeeScript — you simply use a regular statement on a single line.

vardate, mood; if (singing) { mood=greatlyImproved; } if (happy&&knowsIt) { clapsHands(); chaChaCha(); } else { showIt(); } date=friday?sue : jill;

Splats, or Rest Parameters/Spread Syntax

The JavaScript object is a useful way to work with functions that accept variable numbers of arguments. CoffeeScript provides splats , both for function definition as well as invocation, making variable numbers of arguments a little bit more palatable. ES2015 adopted this feature as their rest parameters.

gold=silver=rest="unknown"awardMedals=(first,second,others...)->gold=firstsilver=secondrest=otherscontenders=["Michael Phelps""Liu Xiang""Yao Ming""Allyson Felix""Shawn Johnson""Roman Sebrle""Guo Jingjing""Tyson Gay""Asafa Powell""Usain Bolt"]awardMedalscontenders...alert"""Gold: #{gold}Silver: #{silver}The Field: #{rest.join ', '}"""
varawardMedals, contenders, gold, rest, silver; gold=silver=rest="unknown"; awardMedals=function(first, second, ...others) { gold=first; silver=second; returnrest=others; }; contenders= ["Michael Phelps", "Liu Xiang", "Yao Ming", "Allyson Felix", "Shawn Johnson", "Roman Sebrle", "Guo Jingjing", "Tyson Gay", "Asafa Powell", "Usain Bolt"]; awardMedals(...contenders); alert(`Gold: ${gold}\nSilver: ${silver}\nThe Field: ${rest.join(', ')}`);

Splats also let us elide array elements…

varall, popular, unwanted; popular= ['pepperoni', 'sausage', 'cheese']; unwanted= ['anchovies', 'olives']; all= [...popular, ...unwanted, 'mushrooms'];

…and object properties.

user=name:'Werner Heisenberg'occupation:'theoretical physicist'currentUser={user...,status:'Uncertain'}
varcurrentUser, user, _extends=Object.assign||function (target) { for (vari=1; i<arguments.length; i++) { varsource=arguments[i]; for (varkeyinsource) { if (, key)) { target[key] =source[key]; } } } returntarget; }; user= { name: 'Werner Heisenberg', occupation: 'theoretical physicist' }; currentUser=_extends({}, user, { status: 'Uncertain' });

In ECMAScript this is called spread syntax, and has been supported for arrays since ES2015 but is coming soon for objects. Until object spread syntax is officially supported, the CoffeeScript compiler outputs the same polyfill as Babel’s rest spread transform; but once it is supported, we will revise the compiler’s output. Note that there are very subtle differences between the polyfill and the current proposal.

Loops and Comprehensions

Most of the loops you’ll write in CoffeeScript will be comprehensions over arrays, objects, and ranges. Comprehensions replace (and compile into) loops, with optional guard clauses and the value of the current array index. Unlike for loops, array comprehensions are expressions, and can be returned and assigned.

eat=(food)->"#{food} eaten."eatfoodforfoodin['toast','cheese','wine']courses=['greens','caviar','truffles','roast','cake']menu=(i,dish)->"Menu Item #{i}: #{dish}"menui+1,dishfordish,iincoursesfoods=['broccoli','spinach','chocolate']eatfoodforfoodinfoodswhenfoodisnt'chocolate'
varcourses, dish, eat, food, foods, i, j, k, l, len, len1, len2, menu, ref; eat=function(food) { return`${food}eaten.`; }; ref= ['toast', 'cheese', 'wine']; for (j=0, len=ref.length; j<len; j++) { food=ref[j