CoffeeScript is also one of the good alternatives, and it is worth mentioning, but it is not what i call a light JS transpiler, since it promotes a syntax that differs significantly from the EcmaScript standard (e.g. using the
function keyword throws a compiling error). However Ruby and Python developers usually prefer CoffeeScript over other options.
What is a transpiler anyway?
Well, a transpiler is a tool that takes source code written in one language and transforms it into a language that has a similar level of abstraction.
However, a transpiler is still a kind of compiler, but a very specialized one, targeting a similar programming language as output, so IMHO Babel and TypeScript should be considered transpilers, even though they like to brag about being compilers.
Babel and TS are time-travel machines
However, Babel is a much safer option, since it follows the actual EcmaScript specifications, without additions (except the ability to enable experimental features). TypeScript on the other end adds additional stuff on top of EcmaScript official specs (e.g. Types and Generics to name a few) out of the box, which many could consider a good thing, but definitely out of the standard.
I like optional types, and there are ways to use them in Babel too.
Comparing transpiled output
Babel and TypeScript both use a similar approach to transpiling in many areas, but the output they generate is significantly different. Let's take a simple ES6 class and see what the output looks like.
So, let's take a look at TypeScript output first:
The output is very clean, old-fashioned with a nice IIFE and using prototypes. Arguably most JS developers would write a class this way.
Let's take a look at Babel output:
The Babel output is also an IIFE, but it uses a substantially different approach by using a helper method to create a class which interally uses more modern features of ES5 (e.g. Object.defineProperty etc.).
TypeScript just has a different transpilation philosophy, which is more targeting support (back to ES3 by default) and readability.
"The goal of TypeScript's translation is to emit exactly what a programmer would type when implementing a class or namespace unaided by a tool." - TypeScript spec
Many consider Babel output to be more complex, but again it is very subjective, and some people could consider the complexity a non-issue since Babel is using more robust features of ES5 by default, while TypeScript is going after simpler, readable output, and backward compatibility (ES3 by default).
TypeScript can also be executed with compiler flags to emit a more modern output that utilizes newer ES5 features.
In any case you will have a hard time debugging transpiled code, and arguably TypeScript output is easier to read.
However, SourceMaps are your best friend, and make sure you are using them when debugging.
Both technologies have nice support for all kinds of frameworks, but in my opinion Babel has much better tools, and it is moving faster. Just look at their setup page to understand the wide support:
If you are using Node.js or React.js, you should use Babel. However, if you are using .NET, then TypeScript is your friend, and the Visual Studio tools are pretty awesome.
Also be aware that Babel is ahead of TypeScript in terms of EcmaScript support, which should definitely affect your choice:
Node.js setup of Babel/TypeScript
A better approach is to require a module in your entry script and then it will handle dynamic compiling of all the subsequent requires.
The require hook will bind itself to node's require and automatically compile files on the fly.
All subsequent files required by node with the extensions .es6, .es, .jsx and .js will be transformed by Babel. The polyfill is also automatically required.
However, be aware that TypeScript doesn't have the
require capability built in, but there are some projects to fill the gap. e.g. https://github.com/theblacksmith/typescript-require
And then you can do:
After this point, you can require any .ts module just like .js modules. typescript-require will find out and compile the TypeScript file, resolving any necessary dependencies to other scripts.
Transpilers are nice, and you must use them, since they do make your code better, even though there is a small overhead in development and debugging, but it is a small price to pay for having more mantainable code.