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.