scala-to-jsWhenever coding JavaScript, these are some of the things I miss from Scala:

  • Type-checking
  • Type declarations
  • Classes / Traits / Case-Classes
  • Code modularization
  • IDE support

In this post I want to compare two very promising frameworks that generate JavaScript code from Scala.

Scala.js

Uses the full Scala compiler back-end to generate JavaScript from SBT projects.

Github repo: https://github.com/lampepfl/scala-js.

And more info here.

Pros

  • Covers the whole Scala language
  • Covers a good part of the Scala/Java library
  • Can re-use existing Scala SBT projects
  • Generates source-maps for Scala
  • Optimizes generated JavaScript
  • jQuery and DOM (statically-typed) wrappers available
  • It’s a LAMP EPFL initiative, endorsed by M. Odersky

Cons

  • Long compile times Only when optimizing code (for production). Otherwise very fast incremental compiling.
  • Big generated file Only in development mode. Nevertheless Firefox loads it in under 1 second.
  • Calling Scala.js from existing JavaScript not trivial Calling conventions have been improved.
  • IDE integration issues IDE Integration working without issues now.

Note that all of these “negative” points are in the process to be fixed or improved upon (FIXED!). Also, longer compile times and relatively big file sizes are an inescapable consequence of having the whole Scala language and library available. Perhaps one remaining “issue” is that it’s not trivial to integrate to existing frameworks (like Play). However, in my opinion this is outside of the scope of this project.

JScala Uses

macro-expansion to generate JavaScript code in runtime.

Github repo: https://github.com/nau/jscala .

Pros

  • Trivial to set up
  • Generates code quickly on the fly
  • Generated JavaScript is clean and readable
  • Calling generated code from JavaScript easy
  • Easily integrated in existing Web Frameworks (e.g. Play)

Cons

  • Covers only a subset of Scala</span>
  • Covers only basic parts of the library (relies on JS for the rest)
  • Not trivial to modularize/share code
  • Cryptic macro-expansion error messages

Note that although listed as a disadvantage, the fact that it only covers a subset of Scala and its library might be one of the reasons why code generation is so fast and clean. Being lightweight has its advantages.

Why can’t they collaborate?

This is one obvious question to arise when reading about these two frameworks. It would seem that the project leads are duplicating effort… But in the words of Sèbastien Doeraene, creator of Scala.js:

Sharing code between the Scala.js backend and JavaScript macros is indeed difficult.

The translation from Scala ASTs to JS ASTs simply cannot be shared, because we do not do the same thing: the ASTs reaching the macros are much more complex than those reaching the backend, since those have already been simplified by the compiler transformation phases. Besides, as was mentioned, for macros you need to able to splice values defined in the surrounding Scala code (JsLazy?). Whereas the backend has other requirements: it must encode classes, interfaces, and overloaded methods into a specific scheme in JavaScript.

So all in all, the job of our respective translation phase is actually very different: not the same input, not the same output!

[…] So, I’m afraid we live in worlds that are too different, and that, despite the seemingly related job, we cannot share code effectively.

Which one to use?

This is something very subjective. The first thing I would say is: use whichever approach you feel more comfortable with, and what best suits your needs. My personal opinion would be to use:

  • JScala where you would write small-/medium-sized JavaScript code to really “script” some aspects of your web-page or application. It’s also best suited if your app is mostly server-based, but have some client-based aspects and don’t need advanced Scala features in your client-side-logic. It’s like Coffeescript but with Scala syntax.
  • Scala.js if you have a medium-/big-sized codebase, which deserves a project on its own. Something like a one-page JavaScript application (fat-client), a demo, or a game. If you need the full spectrum of the Scala language and its library, and want to share code between server and client, this might be your safest (and only?) bet. So choose wisely. Or combine both.

Conclusion

For those of use that love the power and elegance of the Scala language and miss its features when coding in JavaScript, these are good news. No matter which approach you use, soon we might find ourselves doing web-based development exclusively in Scala. Sharing code between server and browser, benefiting from compile type-checking and IDE support, and leveraging existing JavaScript libraries. For the ones of us unhappy with JavaScript (and dialects) finally front-end web-development might become fun again!