JavaScript before CoffeeScript

CoffeeScript was written by Jeremy Ashkenas, a Ruby developer who was fed up with the quirks of JavaScript. It was an instant success in the Ruby community. Many people were tired of having to type === instead of ==, of JavaScript's crappy lexical scoping, of having to jump through hoops to set up even the most simple inheritance structure, of variables leaking into the global scope or having to worry about silly things like hoisting.

This was a time when web user interfaces were becoming more complex and backend developers had to spend more and more time writing JavaScript code. For a long time, coding in JavaScript meant you spent 100% of your time using jQuery. And what an epic mess that was!

At that time many people did not consider JavaScript to be a real programming language, because of it's oddities. So when CoffeeScript came along developers (especially Ruby developers) embraced it as a way to make coding in JavaScript suck less. I was one of those developers. I liked that CoffeeScript automatically fixed some of the infamous bad parts of JavaScript for me. I used CoffeeScript for a long time before I realized that I was limiting myself by not learning JavaScript. I disliked JavaScript because I didn't really understand it.

I would like to argue that unless you master JavaScript, you should not be using CoffeeScript. Here are a few reasons why.

Learning how to think in JavaScript is cool

CoffeeScript uses Ruby style classes and classical inheritance. JavaScript is not Ruby. Prototypal inheritance is not classical inheritance. Prototypal inheritance is more powerful and it is worth learning.

When you learn a new programming language, you have to open yourself up to a new way of thinking.

CoffeeScript introduces patterns that are slightly different from JavaScript. In the words of TJ Holowaychuck:

Agreed, the idioms used by coffeescript devs are often quite different than the "norm" in js-land as well, so that alone leads to some pretty awkward APIs when interfacing with "regular" javascript.

You can see some common JavaScript patterns for ES5. The new version of JavaScript, ES6, brings some exciting changes that will undoubtedly generate new patterns.

Is CoffeeScript here to stay?

If I had to make a bet on which language will still be around in 5 years, I'd put my money on JavaScript.

In fact, Discourse decided to move away from CoffeeScript because they felt it might discourage people from contributing to the project.

The future is looking shaky for CoffeeScript. ES6 introduces features like classes, array comprehensions, default parameters and arrow functions that lower the incentives to use CoffeeScript.

As TJ Holowaychuck points in this thread:

I also agree with the ES6 comment, there's very few things that coffeescript really gives you on top of what we'll have as a standard soon, so this seems like a bullet to the foot really.

This makes me wonder if it is worth investing time in learning CoffeeScript at all.

CoffeeScript can be hard to debug without JavaScript

Even with source maps, there were times when I had to look at the JavaScript source to figure out exactly what was going on with my CoffeeScript code. You might think, "So what? If you were writing the code in JavaScript, you would have to look at JavaScript anyway." Well here's the problem...

Here is a simple snippet of CoffeeScript.

list = [1, 2, 3, 4, 5]  
square = (x) -> x * x  
squares = (square num for num in list)  

Here is what it compiles to in JavaScript.

var list, num, square, squares;

list = [1, 2, 3, 4, 5];

square = function(x) {  
  return x * x;
};

squares = (function() {  
  var _i, _len, _results;
  _results = [];
  for (_i = 0, _len = list.length; _i < _len; _i++) {
    num = list[_i];
    _results.push(square(num));
  }
  return _results;
})();

Uhhhh... yeah. Have fun debugging that. In real JavaScript you would use a shim (if necessary) and write:

var list, square, squares;

list = [1, 2, 3, 4, 5];

cubes = list.map(function(x) {  
  return x * x;
});

Ain't no goin' back!

CoffeeScript often generates unreadable JavaScript (see example above). Once you make the decision to use CoffeeScript for your project it would be difficult to switch back to maintainable JavaScript. In fact this blog post chronicles a failed attempt to switch from CoffeeScript to ES6. This is an important consideration from a project management perspective.

Joel Turnbull from gaslight makes a good point in his blog post Does CoffeeScript Have a Future?.

The changes to JavaScript are not only going to improve the language, but are also going to introduce a whole new set of incompatibilities that could potentially break every CoffeeScript compiled application in the wild today.

When JavaScript changes (as it did with ES6), CoffeeScript must change with it. This will require ongoing support from the CoffeeScript community and seems like added risk.

Ultimately the choice between CoffeeScript and JavaScript is one of personal preference, but if you are new to JavaScript, it might make more sense to postpone learning CoffeeScript until you have a good understanding of JavaScript.