Skip to content
AgileLogics
4 min read

Scala.js and Scala Native

Prerequisites: Building with sbt and Scala CLI

The same Scala code can target more than the JVM.

Scala.js: Scala in the browser

// illustrative
//> using platform scala-js
//> using dep org.scala-js::scalajs-dom::2.8.0
import org.scalajs.dom

@main def app(): Unit =
  val button = dom.document.createElement("button")
  button.textContent = "Click me"
  button.addEventListener("click", _ => dom.window.alert("Hello from Scala!"))
  dom.document.body.appendChild(button)

Scala.js compiles to optimized JavaScript. Laminar and Tyrian are popular UI libraries, and full-stack projects share case classes, validation, and JSON codecs between browser and server — one definition, checked on both sides.

Scala Native: native executables

scala --native run hello.scala
scala --power package --native hello.scala -o hello
./hello

Scala Native compiles to a native binary via LLVM: instant start-up and low memory, ideal for command-line tools. It supports most of the standard library and a growing set of libraries, though not arbitrary Java libraries.

GraalVM Native Image

An alternative for JVM applications: GraalVM native-image compiles a whole JVM program — including Java libraries — ahead of time. Scala CLI supports it with --native-image, and it's common for serverless functions and CLIs where JVM start-up time matters.

Cross-building

In sbt, the sbt-crossproject plugin builds one codebase for JVM, JS, and Native, with platform-specific folders for the parts that differ. Many libraries (Cats, Circe, upickle, MUnit) publish for all three.