Lesson 2 / 25

Installing Scala: Scala CLI, sbt and the REPL

Set up Scala with Coursier, run scripts with Scala CLI and build projects with sbt.

The Scala toolchain

The recommended installer is Coursier (cs setup), which installs a JDK if needed plus the Scala tools. Since Scala 3.5, the scala command is Scala CLI, a fast tool for scripts, small projects, the REPL, tests and packaging: scala run hello.scala, scala repl, scala test . and scala package. Dependencies and settings go in //> using directives at the top of a file, such as //> using dep com.lihaoyi::os-lib:0.11.3. For larger, multi-module projects, sbt is the most widely used build tool: build.sbt declares the Scala version and libraryDependencies, and sbt's interactive shell compiles incrementally (~compile recompiles on every save). Mill and Gradle or Maven with Scala plugins are alternatives. Library coordinates use %% in sbt (or :: in Scala CLI) to append the Scala binary version (such as _3) to the artifact name. For editing, use Metals (the Scala language server) in VS Code or other editors, or IntelliJ IDEA with the Scala plugin.

Scala CLI directives and an sbt build

Scripts declare dependencies inline; sbt builds larger projects.

// hello.scala  (run with: scala run hello.scala)
//> using scala 3.3
//> using dep com.lihaoyi::upickle:4.1.0

import upickle.default.*

case class Item(sku: String, price: Int) derives ReadWriter

@main def hello(): Unit =
  val json = write(Item("pen", 4950))
  println(json)                              // {"sku":"pen","price":4950}
  println(read[Item](json).sku)

// build.sbt for a larger project
// ThisBuild / scalaVersion := "3.3.6"
// lazy val root = project
//   .in(file("."))
//   .settings(
//     name := "orders-service",
//     libraryDependencies ++= Seq(
//       "com.lihaoyi"   %% "upickle" % "4.1.0",
//       "org.scalameta" %% "munit"   % "1.1.0" % Test
//     )
//   )

A scooter and a truck

Scala CLI is a scooter: perfect for quick trips such as scripts, experiments and small tools. sbt is a truck: slower to start, but built to carry large multi-module projects and long build pipelines.

Quick check: What does %% do in an sbt dependency?

  • Marks the dependency as optional
  • Downloads the source code
  • Excludes transitive dependencies
  • Appends the Scala binary version (such as _3) to the artifact name
Answer

Appends the Scala binary version (such as _3) to the artifact name — Scala libraries are published per Scala binary version, and %% selects the right one.