This post is taken from my blog so be sure to check it out for more up-to-date content π
JavaScript is great for a number of use-cases. It's pretty well-designed language. But the truth is it lacks some features. Anything from type-safety and custom operators is not present in JS - at least for the time of writing. However, these and other syntactic sugar can easily be implemented using any kind of compilation step. You may also not like JavaScript so much but still, want to code web apps. You may, of course, you some tool like Emscripten to compile your favorite language (in this case C/C++ but there are options for e.g. Java) to JavaScript for in-browser use. But there are other options. Great many programming languages exist that provide first-class/only support for JS compilation target. These can attract you with their syntaxes and other features like editor support. Believe me or not, there are quite many. In this post, I'm going to introduce you to my list of Top 10 programming languages with JS as a compilation target. Keep in mind that I haven't extensively tried them all... yet. So this is a mostly based on my first impression, so... I hope this will be interesting for you. π
10. Scala.js
Scala.js allows you to compile Scala programming language to JavaScript. With it, you can write a modern, post-ES6-like code with a strong type system. This means great IDE support and features like classes, modules, types, and macros for extending the language out-of-the-box! Scala.js claims to have near-native JS performance and support for standard JS libraries through facades types system. If you've already programmed in Scala, this might be something for you. Also, project page provides a great guide for those coming from ES6 background. Let's sum up some basic differences.
// Comment
/*
Multiline comment
*/
var mutable: String = "variable"
val immutable = "constant"
def exampleMultiplyFunction(x: Double, y: Double): Double = x * y
abstract class Logger() {
def log(msg: String): Unit = {
println(msg)
}
}
class ConsoleLogger() extends Logger() {
override def log(msg: String = ""): Unit = {
if (msg != "") println(msg) else println("console.log equivalent")
}
}
new ConsoleLogger().log()
This might not be the full showcase of Scala's possibilities or even valid "Hello World!" but I think this can give most programmers a basic idea of how Scala's syntax looks like. Of course, you can also utilize the whole Scala standard library with a great number of built-in types and structures. For more Scala's goodness, you can visit the Scala language website or the one of Scala.js. I think it goes without saying that when writing pure Scala you can achieve cross-platform code through its JVM and LLVM targets.
9. Haxe
Haxe is a truly cross-platform solution for dynamic and interactive apps development. It can be compiled to a number of other languages, including JS. Because of that, Haxe has a number of use-cases - games, server backends, websites, professional software, and counting. The website provides great documentation with an impressive amount of details. As for the language itself, it has nice object-oriented and type-safe syntax (great IDE support) with various other features like metadata and compiler's macros. This time, a proper "Hello World!" can be used. π
class Main {
static public function main():Void {
trace("Hello World");
}
}
With a quick look of my eye, I can say that Haxe's syntax is vastly superior to the one of JS, mainly due to the type system, macros, and all compiler goodness. Haxe seems like a good choice for cross-platform apps and games.
8. Dart
Dart has gained quite a boost in popularity lately, due to the Flutter framework. Flutter can be used to develop Android and iOS application with ease. And it's actually written using Dart! On to the Dart then. It's a VM-based language created by Google, so it can run on its VM as server backend, on the web when JS-compiled and on other x86 and ARM platforms (especially for mobile with Flutter). Its syntax is inspired by C, C#, and Java with the vast standard library. The example below is taken from DartPad (Dart online playground) Fibonacci example:
void main() {
var i = 20;
print('fibonacci($i) = ${fibonacci(i)}');
}
int fibonacci(int n) {
return n < 2 ? n : (fibonacci(n - 1) + fibonacci(n - 2));
}
This piece of code clearly shows Dart typed and object-oriented nature. What's also interesting is Dart's focus on asynchronous programming with structures like Futures and Streams. Besides all that, IDE support is great with all typed-language features that Dart posses. All of this makes Dart perfect choice for demanding web and mobile apps.
7. Elm
Unlike previous positions on this list, Elm is only compilable to JS and other web languages (HTML). Its primary target is web apps development with the custom-made, high-performance implementation of virtual DOM. Elm fulfills its purpose just right as a way to combine HTML and JS in nice, readable form.
import Html exposing (text)
who = "World" -- comment
main =
text ("Hello " ++ who ++ "!")
Aside from that, Elm syntax might require some time to get used to. Its type system and IDE support will help with that.
6. Imba
Imba is yet another web-apps-development-focused language. I think of it as a younger Elm competitor. With its memoized DOM, Imba claims to be faster than all of today's virtual DOM implementations.
# Comment
console.log "Hello World"
tag HelloWorld
def render
<self> "Hello World"
Imba.mount(<HelloWorld>)
In Imba DOM nodes are "first-class citizens" so that you can operate with them just like with other variables. What's a bit sad is that Imba doesn't have a strong type system, meaning a bit worse IDE support. Also, the fact that it's compared and provided as React competitor makes it a bit funny. You know, because React is a library and Imba is advertised as a language. π
5. Nim
Returning to more standard programming languages, we're greeted with Nim. Nim is statically-typed, garbage-collected language that can be compiled to C, C++, and JS. It has indentation-based syntax inspired by Python and great support for meta-programming and macros. Generally, it all comes down to great performance, interesting syntax, and editor support.
import strformat
type
Person = object
name*: string # Field is exported using `*`.
age: Natural # Natural type ensures the age is positive.
var people = [
Person(name: "John", age: 45),
Person(name: "Kate", age: 30)
]
for person in people:
# Type-safe string interpolation.
echo(fmt"{person.name} is {person.age} years old")
IMHO Nim looks like an interesting project, that's actively developed and worth looking. π
4. ClojureScript
ClojureScript is a Clojure to JavaScript compiler. ClojureScript fully embraces the idea of functional programming. As such it has a great collection of built-in immutable data structures. This provides a new way of thinking for object-oriented programmers. The syntax might seem a little awkward as almost everything is a function, but it can be got used to, given time. π
(ns hello-world.core)
(println "Hello world!")
This might be worth a look if you're planning on trying out the functional programming techniques in general.
3. ReasonML
Opening the best three, we have Reason. Reason is a language developed by Facebook, focused on type-safety and interoperability. It's based on JS and OCaml ecosystems. As Reason is coming from the guys behind React, it has really good support across the board. The type system is nice and general development experience just rocks. βAlso, Reason has been well-designed to feel familiar with JS developers while preserving OCaml best features, including the type system.
let rec fibonacci = n =>
switch (n) {
| 0 | 1 => 1
| n => fibonacci(n - 1) + fibonacci(n - 2)
}
for (x in 1 to 10) {
Js.log(fibonacci(x));
}
2. Kotlin
Kotlin is a JVM-based programming language with support for Android development, JS, native LLVM binaries and, naturally, JVM. It has an awesome type system, great interoperability and fantastic editor support (JetBrains' project). The project has gained a lot of popularity these days. And it's not without a reason. You know, cross-platform, nice syntax and a vast amount of features combined with good performance lead to great success.
class Greeter(val name: String) {
fun greet() {
println("Hello, $name")
}
}
fun main(args: Array<String>) {
Greeter(args[0]).greet()
}
1. TypeScript
I might be a little biased here. TypeScript is my favorite and go-to language when it comes to JS compilables. It may not be cross-platform or has any kind of special feature, but there's only one thing it's meant to do - provide type system for JS - and it does it well. It also allows to use some features from newer ES-Next standard that aren't supported in browsers at the time. The syntax besides types is pure JS and that's how I like it. As for the types themselves - they are responsible for absolutely staggering IDE support for both TS and JS projects. What's more to be said? π
export class Fibonacci {
index : number;
fibonacciNumber : number;
public calculateFibonacciNumber() {
this.fibonacciNumber = this.calculate(this.index);
}
private calculate(i : number) : number{
return (i <= 2) ? 1 : this.calculate(i -1 ) + this.calculate(i -2);
}
}
There's more...
This was just my personal opinion on best JS "compilables". I hope that I interested you in at least a few of these or even convinced you to try one. Trust me, there are many more awesome programming languages out there. Many provide functionalities far beyond JS. Maybe one of them will become your go-to language of choice? Anyway, this was my list. Consider suggesting other options in the comments below. Also, share this article, so others can find it easier. For more content follow me on Twitter or on my Facebook page. π¦
Top comments (9)
I can only speak for TypeScript and Elm. And I must say that for those of you that really value the ergonomics of the language you use, Elm trumps JS & typescript. Not only do you not get runtime exceptions in Elm, but reasoning about complexity in Elm is much easier given the explicitness of its type system. In typescript you do not have a
Maybe
type which makes the notion of nullable objects explicit. In typescript you do not have aResult
type, which makes failure situations explicit as well. All these additional types might make it seem like a burden to deal with, but what it actually does is force you to reason about all the various states of your program ahead of time instead of after you release and realize your users are looking at a runtime error caused by an edge case you didn't think about.Edit: Spelling :)
to
is a better example
I wish TypeScript wasn't so shy of adding syntax that actually outputs something.
But at least on the typechecking side
as const
might be coming as early as 3.3, andopaque
types finally seem in the works as well.Maybe it will go through a second rebirth and finally stop me looking for alternatives for the general small-scale case.
Typescript seems the best , as with typescript you are extending your js knowledge and organising it , unlike other's where you are re-learning a whole new language and TS code can be easily used with any existing js project , be it server side nodejs or client side jquery and has a strong community
Have you used TypeScript on large (10,000+ LOC) projects? It works well when you don't have to use 3rd party packages (React, lodash, etc) because the run-time code for these packages is completely separate from the types. This means that close to 90% of the time, the types are wrong. Which leads to runtime exceptions becasue the typesystem is a completely inacurate representation of the runtime characteristics of the program.
Also, given that you are most likely interfacing with JS, a developer is prone to use the
any
type way too often, which ultimately defeats the purpose of writing typescript in the first place.Have you considered that maybe learning a language completely different from JS might help you become a better JS developer? Haskell and Elm are good examples of this. They are radically different from JS and force you to think about your programs in a completely new way. But this thinking can be applied back to JS to help you write more resilient code.
Edit: Check out this blog post where I get into a bit of detail on TypeScript's flaws dev.to/_gdelgado/the-economics-of-...
There's also WebAssembly
By the way, "compile-to-JS languages" is probably a better way of saying "JS compilables"
Other than that, nice list! π
I'm thinking of starting with Kotlin, a coworker showed me some code and it looks an interesting language.
+1 for Haxe, it's one of my favorite languages to use.