JavaScript Transpiled Languages

Introduction

JavaScript is now the assembly of the web. Rather than wait on language innovation in the design by committee web standards world, many choose to use more advanced languages and tooling to develop in, that then compile to JavaScript.

Transpilers, also known as source to source compilers or transcompilers, are used to translates source code to another form of source code. They are popular and numerous, not just for JavaScript, but also for C, and many other languages. In this article I cover why they are valuable for JavaScript developers, give details on the popular ones in the community, and go over the use case workflow for each.

I’ve chosen 6 of the most popular JavaScript transpiled languages used for client web application development:

  1. CoffeeScript
  2. TypeScript
  3. AtScript
  4. ClojureScript
  5. ES6 to ES5
  6. Dart

What

Transpilers allow you to convert your source code in one language, either 1 file or many, into another language. In JavaScript’s case, you typically write in 1 language such as CoffeeScript, and using a build system such as Gulp or Grunt, it will compile your .coffee files to .js JavaScript files. Most also generate source maps for more streamlined debugging.

Another use case is the use of annotations where you write comments in the code that have special meaning and reflection API’s are utilized at runtime to inspect the code’s meaning and act accordingly. Examples include signifying what type the class is without the need for inheritance which is what AtScript does on top of the TypeScript compiler. Another is describing the static typing contract the function has in JavaScript using the Google’s Traceur compiler. They both will interpret those code comments and generate JavaScript with those special meanings applied.

Why

Transpilers in the non-JavaScript past were utilized to convert large code bases to a newer language (such as Python 2 to 3), an old API to a new one, or runtime platform where doing it by hand was impractical and error prone.  In the JavaScript world, there are a variety of reasons.

The primary reason is that JavaScript innovation is slower than open source and private offerings. It takes a long time to get an ECMAScript feature from committee standard to implemented in all green field browsers. You can use some of those features, and more, in the other languages, today, and still have it run on the standards based, ubiquitous web platform.

Here are few more often cited reasons:

  1. JavaScript evolution slow compared to other languages
  2. open source and private languages evolve faster, have more features
  3. sometimes less code
  4. better code
  5. organized code
  6. more language features
  7. leverage existing talent
  8. leverage existing libraries
  9. more efficient runtime
  10. developers are more productive
  11. future proof
  12. clearer code

History

LLVM-3-0-Officially-Released bwSource to source compiling is not a new concept.

In 1981, Digital Research had a program that converted ASM source code for the Intel 8080 processor into A86 source code for the Intel 8086.

In 1983 Cfront was the original compiler for C++ which compiled C++ to C.

In 2000, the LLVM project was created with a collection of modular and reusable compiler and toolchain technologies. It is used for compiling a variety of of gcc 4.2.1 languages to C. A few of these include Lisp, ActionScript, Ada, D, Fortran, OpenGL, Go, Java, Objective-C, Python, Ruby, C#, and Lua are just a few.

In 2006, Google released Google Web Toolkit, called GWT. It enables developers to build cross browser web applications in Java.

Many other source to source compilers have been written for everything to Fortran to Python to either convert an older language to a newer platform, or from an old API to a new one.

Source to source compilers are an old, accepted practice.

CoffeeScript

coffeescript-logo bw

Why

CoffeeScript attempts to expose the good parts of JavaScript and hide the bad parts. Created by the guy responsible for Underscore and Backbone. Benefit is class syntax, fixes JavaScript’s operators, and has a terse & safe syntax.

Features

  • classes with inheritance and super keyword which abstracts away Object.prototype
  • fixes == equality to work as expected
  • arrow functions and other shortened initializers for terse code
  • shortened loop syntax with optimized output and additional keywords
  • literate coffeescript option which allows code to be written in Markdown
  • lexical soping of variables (i.e. no need for var keyword)
  • terse if else then statements, no parentheses or brackets required
  • rest based parameters
  • array slice syntax similiar to Python
  • implied return statement, no need to type it
  • statements converted to expressions inside closures
  • uses english for equality operators and compiles down to safe usage
  • provides existential operator for checking existence of variables
  • Array/Object destructuring which allows for multiple return values from functions
  • Function binding for ensuring this scope remains intact
  • safter switch statements
  • chained comparrisons
  • String interpolation
  • multiline and block strings
  • Block Regular Expressions (borrows from Perl’s /x)

Pros

  • Compiles to nice JavaScript providing good escape hatch if team ends up not liking it
  • Basically JavaScript, not much to learn
  • terse code
  • fixes many of JavaScript’s basic language problems with safety included
  • makes classes useable in JavaScript

Cons

The only con is some developers wish to code only in CoffeeScript, and others do not wish to code in CoffeeScript. These are often quite strong feelings.

TypeScript

CRS-56479-bw

Why

TypeScript provides opt-in static typing, class and module syntax, and is based on the ES6 spec. It was created by Anders Hejlsberg of Turbo Pascal, Delphi, and C# fame. Benefit is strong typing with ability to use against 3rd party libraries, package & classes, and backed by Microsoft.

Features

  • define strongly typed globals via declare
  • integrate strong typing to 3rd party libraries via declaration files
  • strong typing for both built-in primitives, classes, and interfaces
  • type inference with basic primitives, classes, and interfaces
  • interfaces can be applied to basic Objects and classes
  • function literals
  • class constructor initializers
  • default parameters
  • multiple constructor signatures
  • class inheritance with super keyword
  • package support via private and public modules
  • compiler supports generating AMD or CommonJS modules
  • arrow syntax for function binding
  • generics
  • … and a lot more.

Pros

  • Compiles to nice JavaScript providing good escape hatch if team ends up not liking it
  • strong typing allows larger projects and teams to find bugs early w/o writing unit tests
  • classes are made usable in JavaScript with inheritance
  • Offers package management for classes, unlike CoffeeScript
  • Like CoffeeScript, a lot of syntactic sugar

Cons

Typing is not enforced at runtime, only compile time. Also, same problem with CoffeeScript: developers either love or hate it.

AtScript

AngularJS_logo.svg bw

Why

Angular’s growth in the Enterprise has shown the limits of JavaScript, thus the natural evolution is to a more mature language: TypeScript. However, TypeScript is missing application development features, so the Google Angular team is working with the Microsoft TypeScript team to modify the language & compiler. Specifically class annotations and runtime assertions resulting in an enhanced TypeScript called AtScript.

Features

Same as TypeScript. The two additional ones are class metadata annotations and runtime assertions for type safety at runtime. The class metadata annotations are used to denote the Angular component types without having to inherit from a specific class or work within a specific lifecycle API. While it may seem Angular specific, any framework can benefit from class and variable metadata annotations consumed at runtime. Aurelia is another MVC framework that supports AtScript.

Pros

All the Pros of TypeScript including:

  • your types being enforced at runtime
  • can swap out the assertion library with your own
  • easier & more readable way to declare Angular component types compared Angular 1.0’s methods
  • backed by both Google and Microsoft

Cons

Same as TypeScript, including at the time of his writing, these features are in active development.

ClojureScript

clojure-icon-bw

Why

Clojure has gained in popularity because it is a functional language that runs on the JVM with concurrency. This same language can be utilized to build client side applications through compilation to JavaScript via the Google Closure compiler (note the “s” vs. a “j”). Touting the same benefits of JavaScript with Node, being the same language used on the client and server sharing some of the same libraries.

Features

  • functional language, dialect of Lisp
  • runs on the JVM
  • supports concurrency written in a synchronous way like Go
  • optional type hints and type inference to avoid Java reflection
  • immutable data structures
  • same language used on the server

Pros

  • one language for front end and back-end development
  • supports streams and promises native to the language
  • immutable data structures are the norm with mutable support enabling easy concurrency with rewind testing support
  • this makes working with React’s shouldComponentUpdate method insanely efficient and succinct to write
  • Clojure is a Functional Language

Cons

  • No popular MVC frameworks ported yet (ie Angular, Backbone, Ember). Although one can utilize Purnam, most of these MVC frameworks are OOP based and encourage Clojure Models to be some sort of atom as opposed to being Functional based and using Collections and Streams as the Models.
  • … like the Pro, Clojure is a Functional Language

ECMAScript 6 to ECMAScript 5

es6-logo-bw

Why

Utilize ECMAScript 6 features of the future, today, while supporting the older browsers of yesterday. Still writing JavaScript, no need to learn a new language. Get a leg up on writing the JavaScript of tomorrow to ensure code bases are easier to modify/reuse in the future. The most common way to do that today is to utilize the 6to5 or Google Traceur transpilers.

Features

  • classes – no need to agree on an OOP JavaScript pattern or library
  • modules – standardized way of organizing code like Java packages
  • module loading supporting dynamic loading, execution sandbox, and module cache manipulation
  • private variables
  • tighter code through arrow functions, object literals
  • template strings – safer string creation without a library
  • destructuring with soft fail pattern matching
  • constants
  • iterators like Java and “for of” support
  • generators for creating green threads for long running processes
  • Map, Set, and Weak versions – updated collection data structures commonly used
  • Proxy support
  • Symbols, more powerful Strings for lookups in Maps and Objects
  • easier to sub-class native classes
  • various new API’s to String, Number, Object, and Math
  • native Promises
  • reflection api for easier Proxy creation and other higher level tooling
  • tail calls – safer recursion

Pros

  • most ES6 features
  • team doesn’t have to learn a new language, it’s simply JavaScript compiling to JavaScript
  • you’re coding the future, today
  • classes and modules help code quality because of consistency, a core problem in JavaScript applications
  • module loader helps solve common performance and security issues with JavaScript applications
  • various features that aren’t yet implemented are emulated via shims/polyfills that perform well enough
  • using technology based on web standards ensuring longer term support

Cons

  • existing JavaScript libraries and frameworks need to be ported, brought into build system, or maintained separately
  • generators cannot be effectively polyfilled, though polyfills do exist
  • modules and their loaders do not solve module problem thoroughly… yet. They are client specific, avoids Common JS, and makes sharing code with Node/io.js challenging. Solution is to use Browserify and put ES6 classes on module.exports.
  • most JavaScript coding standards do not yet exist for ES6.
  • This includes syntax, code quality, and coverage tooling as well.
  • For many teams not yet used to developing in more enterprise languages (i.e. heavy use of class and module keywords in large codebase), this can be a huge change for them. This is not necessarely the “safe option” because “it’s just newer, standards based JavaScript”

Dart

dart-logo-wordmarkbw

Why

For Java developers, a mature OOP language with functional elements on both client and server. For full stack developers using JavaScript frameworks on the client and Node on the server, a better language & compiler for larger scale applications. For gaming developers, much of the same benefits they get with TypeScript, but with more functional elements, cross browser API’s abstracted for them, with a more powerful compiler to optimize their code. All get a Google run package management system and gain immense runtime speed when code runs in the Dart Virtual Machine. Dart is the full package.

Features

  • Dart language – like JavaScript, object oriented, optionally strongly typed, generics, classes, packages, libraries, promises, streams, and other functional features including basics like no undefined, and == that works like you’d expect it to.
  • Dart SDK – libraries for client and server, cross browser DOM and other HTML5 API abstractions.
  • pub – package management system, much like npm or bower
  • Dart Editor – Eclipse based IDE with code hinting, intellisense, and basic refactoring abilities. Includes a GUI on top of pub so you can add/remove dependencies as well as create you own.
  • Dart VM – runtime utilizing .dart code to run in a virtual machine for great speed. Currently implemented in Chromium with future plans to bring to Chrome and hopefully implement in other browsers.
  • dart2js – advanced compiler that converts dart code to JavaScript. Includes generic and data type optimization, tree shaking, and various metadata/reflection/annotation capabilities. You can optionally leave in runtime assertions for data typing.

Pros

  • language better suited for larger teams & applications built from scratch specifically for building client and server web applications
  • mature compiler built with web applications in mind, often generating faster executing JavaScript
  • Built & run by Google
  • Core part of the Angular 2.0 build lifecycle
  • A suite of tools for building web applications
  • Where Chrome only is an option (kiosks, enterprise networks, etc) Dart VM helps gain fast speed, yet not having to use C/C++ for Native Client development
  • same language & libraries used on client and server
  • easier runtime module creation with retained strong-typing for application optimization (as opposed to custom grunt/gulp builds + ocLazyLoad or require.js packaging).
  • supports debugging directly from an Android device

Cons

  • Unlike CoffeeScript, TypeScript, ClojureScript, and ES6 to ES5, Dart does not provide an easy escape hatch. The transpiled JavaScript is built for a specific runtime. Thus it is not easy to “try before you buy” and thus salvaging your work.
  • This Dart JavaScript runtime specific code causes challenges when attempting to integrate into existing applications. There is JS interop, however, that allows Dart JavaScript to non-Dart JavaScript communication

Conclusions

javascript-and-the-good-parts-bw

There are many other transcompiled languages, platforms, and compilers not covered here. The desire for developers to improve various other parts of JavaScript and customize to their team’s workflow has resulted in a plethora of choices for teams. While it’s not always clear which choice is the best for the team, what is clear is that transcompiling is a normal practice in JavaScript development, integrates nicely with most build systems, and will continue to improve.

Special Thanks

Thanks to Alan Shaw and Daniel Glauser (hire Daniel) for the impromptu Google Hangouts to give my peers and I the lo down on Clojure. Thanks to David Nolen for answering my questions and hooking me up with some good Clojure resources to learn. His blog is crazy and awesome, btw, encourage you to read even if you’re a client dev.  Thanks to Joel Hooks, Robert Penner, and Ben Clinkinbeard for clarifying some some finer points and sharing code. Thanks to beer for helping me get through Clojure training.

Title artwork by Ry-Spirit.

12 Replies to “JavaScript Transpiled Languages”

  1. You’ve missed an important one: Haxe, which compiles to JS… also Java, C#, C++, PHP, Flash, and Python :D
    Looking at only its JS output, it is comparable to TypeScript and CoffeeScript, and much cleaner then Dart.

    1. I couldn’t find anyone using Haxe for application development on the web, all were doing game development.

      As a former Flash & Flex developer, I spent a lot of my career utilizing Nicolas Cannasse’s work on MTASC. My, and many other developers, lives were significantly better because of his efforts. Haxe’ language and tooling improvements over AS3 are great, especially with the failure of the ECMAScript 4 language improvements to come to fruition. However, it has been years now, and no one I know in the Enterprise sphere is hiring for that. They’d rather use native iOS, native Android, some lightweight architecture for browser & Node, or the existing heavyweights like Java, .NET, Ruby, Python, and PHP. I would of loved for Haxe to take off in the web development sphere, but it’s clear full stack developers who actually want their stack to utilize the same language are rare.

          1. Your selection is fair enough in your position.

            Using Haxe is still a decision organisations will do internally and when we need to recruit we just hire good JS/AS/Java developers and get them up to speed – quicker and simpler than looking specifically for Haxe devs.

          2. It’s a bit surprising how an organization with a user-base of 50 million doesn’t qualify as “large organization” for you – especially since reaching such numbers with a comparatively small staff suggests greater productivity, better tools and hence smarter decisions.

            But sure, when today’s advanced has become tomorrow’s mediocre people who stopped following progress in language design yesterday will be impressed. Congratulations.

            For everyone else, take a good look at Haxe, js_of_ocaml, scala-js, Elm, Idris, PureScript, the various Haskell transpilers, etc. – I’m sure you get the point. There are developer-years to be saved.

  2. A couple of points to add regarding Dart, TypeScript and AtScript.

    1 – Dart has been submitted to ECMA for standardization. One of the most cited fears devs have towards Dart is that Google may pull the plug on it and then they’re left with no support. Well standardization does away with that fear. See links below.

    http://www.i-programmer.info/news/98-languages/6713-googles-dart-becomes-ecmas-dart.html
    http://www.ecma-international.org/publications/standards/Ecma-408.htm

    2 – Although mentioned in the article it should be pointed out again that unlike CoffeScript and a few others Dart is not just a language. It is a language AND A framework! Dart comes with a complete and robust set of standard libraries covering networking, io, html, collections, async support, etc. You won’t find yourself searching the web for a 3rd party library – it is truly batteries included.

    3 – AngularDart – want to see how AngularJS 2.0 is going to work? Look no further than AngularDart 1.0. One of the driving reasons the Angular team chose to go with AtScript is so that it allowed them to have a single source code base that could be used to generate libraries for both AngularJS and AngularDart.

    http://victorsavkin.com/post/86909839576/angulardart-1-0-for-angularjs-developers
    https://angulardart.org/

    4 – one of the most important features built into Dart is hindsight. As the old saying goes hindsight is 20/20 and the Dart team took a long hard look at all of the lessons learned over the past 20+ years of web development and incorporated purposeful and well thought-out solutions into the language. That alone is invaluable.

    5 – TypeScript/AtScript – today’s transpilers will soon be tomorrows standard. The Google and MS teams plan to converge their work at some point in the future and submit it to the ECMA for inclusion into the JS standard. Like it or not, types are coming to JS and will soon be the industry standard. JS is growing up and it will mean better tooling and more reliable programs.

  3. Very nice summary of the currently options. Of course readers already in love with one of these will feel that their feathers are ruffled, but what are you gonna do? I thought you were quite objective.

    I would like to hear your thoughts on the recently announcement by Microsoft/Google, that Angular 2.0 will be written in TypeScript (although still support straight JS). As a current enterprise AS/Flex developer, I need to plan a transition to one of these in the coming years. As someone who loves the highly-organized MVCS way of doing things (e.g. Robotlegs), Angular2/Typescript sounds very appealing.

    1. As a former Flex dev, you’ll love TypeScript and feel right at home. It’s like a better AS2. Angular 2 is putting Assert.js to emulate what we had in AS3 with runtime exceptions. Although dated, I have an article on TypeScript for ActionScript developers. You’ll still see a bunch of nice things in there, and I still don’t cover what’s happened in the past 3 years to make TypeScript even cooler.

      That said, screw all that, Dart is awesome. Career wise? Stick to ES6 if you’re scared, TypeScript if you’re not, Dart if you’re brave or want to work at Google.

      1. Thanks for the reply! Yes, I read your Typescript for ActionScript post recently; quite helpful.

        TypeScript/Angular appears to hit the sweet spot for my needs: a strong level of adoption and industry backing, so that the risk of having to completely reinvent the wheel in five years is relatively low; and yet an AS-like MVCS DI environment, that I’ve come to experience as essential for complex enterprise apps.

        I don’t dismiss the possibility that Dart and/or CoffeeScript (and/or WhateverComesNext) might be the better mousetrap, when evaluated solely on technical merit; but I picked Flash/Flex/RL based solely on technical merit; it was a great run, I think I’m done on the revolutionary ladder for the moment.

        So yeah, not scared; but not brave I guess. : )

Comments are closed.