Kotlin to Javascript

In my opinion, one of the most interesting Kotlin features is the ability to transpile into Javascript. I’m a huge fan of GWT (Java -> Javascript), a lot of my projects are working in the web with GWT (like http://chess.mobialia.com or http://12chess.com), and I need to know if Kotlin is going to be able to replace Java+GWT in the near future.

So I tried to compile the Carballo Kotlin code to JS (as a NodeJS app) in the “js” branch: https://github.com/albertoruibal/karballo/tree/js, and I couldn’t make it work yet. I found some problems that I will detail in this post.

GWT includes a reduced version of the JRE, without some classes and methods, but Kotlin is much more radical: To compile a Kotlin code to JS, it cannot reference any java.* class, so forget about java.lang.*, java.util.* or java.io.*.

No basic java types

Integer, Character, Boolean… are a Java classes and they cannot be used, so a lot of common operations must be done the “Kotlin way”, i.e.:

Integer.parseInt(myString) -> myString.toInt()
Character.toLowerCase(myChar) -> myChar.toLowerCase()

Emulating Java classes: System, Math, Random, Arrays, Date

These classes are not available when building to JS. To avoid changing the original code and migrate seamless from JVM to JS, I created auxiliar classes with the methods used in the code:

  • System: I implemented currentTimeMillis() (calling the JS Date object), exit(), arraycopy(), and an empty gc()
  • Math: When building for JS, the java.lang.Math class must be replaced by kotlin.js.Math, using this class avoids to change a lot of code
  • Random: Using kotlin.js.Math.random()
  • Arrays: Implementing some variants of the fill() method
  • Date: partial implementation to get the current date

Other problems

  • IntelliJ does not allow to mix the Java and the JS Kotlin stdlib in the same project, so I hat to create a different branch “js”
  • No Threads nor Coroutines support in JS jet
  • Kotlin’s readLine() (to read lines from stdin) is only available in the JVM stdlib
  • String.toBoolean() is only available in the JVM stdlib, I fixed it defining a extension function in the same package: 
    inline fun String.toBoolean(): Boolean = "true".equals(this.toLowerCase())
  • No support for asserts in the JS compiler
  • Some annotations aren’t available @JvmOverloads, @Throws…
  • No LinkedList
  • No StringBuffer, but in this case it’s better to use Kotlin’s StringBuilder
  • Missing StringBuilder.setLength() method (I sent a pull request to Kotlin implementing setLength() and substring())
  • It does not allow returns into synchronized blocks
  • No printStackTrace() on exceptions
  • No JUnit tests in JS, so I removed the tests in the “js” branch

Overall conclusion

After solving all these problems, the Kotlin2JS compiler is introducing bugs that don’t allow the karballo engine to work. You can use social media graphics software to compile instead.

Kotlin2JS isn’t production ready, and years behind GWT.