Skip to main content

Scala.js

Scala CLI can compile, run, test, and package Scala.js sources.

One caveat is that Scala CLI doesn't have support for JS bundlers (such as webpack) like scalajs-bundler has. For this, you'll have to handle bundling yourself, with the .js file generated by scala-cli.

In order to run Scala.js sources, node is required.

Configuration

Enable Scala.js support by passing --js to scala-cli, such as:

scala-cli Test.scala --js

Dependencies

This section is currently a work in progress, but here are some initial notes:

  • Beware platform dependencies
  • run / test / package should all work

Package

Packaging Scala.js applications results in a .js file, that can be run with node:

HelloJs.scala
import scala.scalajs.js

object Hello {
def main(args: Array[String]): Unit = {
val console = js.Dynamic.global.console
val msg = "Hello World from Scala.js"
console.log(msg)
}
}
scala-cli package --js HelloJs.scala -o hello.js
node hello.js
# Hello World from Scala.js

Module Split Style

Smallest Modules

Passing --js-module-split-style smallestmodules to the package sub-command creates js modules that are as small as possible. Scala.js linker generates a lot of js modules, which are copied to the output directory.

SmallestModules.scala
import scala.scalajs.js

case class Foo(txt: String)

object Hello extends App {
println(Foo("Hello World from Scala.js").txt)
}
scala-cli package --js SmallestModules.scala --js-module-split-style smallestmodules --js-module-kind es --output hello
echo "{\"type\": \"module\"}" >> package.json # enable ES module
node hello/main.js
# Hello World from Scala.js

Small Modules For

Passing --js-module-split-style smallestmodules to the package sub-command creates many small modules as possibles for the classes in the listed packages (and their subpackages). To define packages use jsSmallModuleForPackage parameter.

SmallestModules.scala
//> using jsModuleKind "es"
//> using jsModuleSplitStyleStr "smallmodulesfor"
//> using jsSmallModuleForPackage "com.example.test", "com.example.example""

package com.example.test

import scala.scalajs.js

case class Foo(txt: String)

object Hello extends App {
println(Foo("Hello World from Scala.js").txt)
}

Emit source maps

Passing --js-emit-source-maps to the package sub-command emits source maps alongside js files. To set the destination path of source maps, pass --js-source-maps-path flag with the argument.

The following command emits a main.js.map alongside js files:

scala-cli package Hello.scala --js --js-emit-source-maps
# Emitted js source maps to: ./Hello.js.map
# Wrote Hello.js, run it with
# node ./Hello.js

Scala.js DOM support

Pass --js-dom to compile, run, or test to simulate a DOM in Node.js

note

If you see the following error, it means that you don't have the jsdom library installed to simulate the DOM.

Error: Cannot find module 'jsdom'

To fix it, install jsdom locally for your project. You can install install jsdom as follows:

npm init private
npm install jsdom
Hello.scala
//> using lib "org.scala-js::scalajs-dom::2.1.0"
//> using platform scala-js

object Hello {
def main(args: Array[String]): Unit = {
val parNode = document.createElement("p")
parNode.textContent = "Hello World"
document.body.appendChild(parNode)
}
}
scala-cli Hello.scala --js-dom

Using Directives

Scala.js options are supported by using directives in Scala CLI:

--js-version

The Scala.js version

--js-header

A header that will be added at the top of generated .js files

For more options, see our using directive section.

Supported Scala.js Versions

In the future, the Scala CLI will be able to support any version of Scala.js independently of the version of scala-cli. But for now, there are some limitations and it isn't possible to use each version of Scala.js.

The table below lists the last supported version of Scala.js in Scala CLI. If you want to use newer Scala.js, update scala-cli.

Scala CLI versionsScala.js
0.0.91.7.1
0.1.01.8.0
0.1.11.8.0
0.1.21.8.0
0.1.31.9.0
0.1.41.10.0
0.1.51.10.0