Skip to content
AgileLogics
6 min read

Building with sbt and Scala CLI

Prerequisites: Packages and imports

Scala CLI for scripts and small projects

Scala CLI configures everything with //> using directives at the top of a file:

// illustrative
//> using scala 3.9
//> using dep com.lihaoyi::upickle:4.1.0
//> using dep com.lihaoyi::os-lib:0.11.4

@main def report(): Unit =
  val data = ujson.read(os.read(os.pwd / "data.json"))
  println(data("name").str)
scala run report.scala     # compile and run
scala test .               # run tests (*.test.scala files)
scala package report.scala --assembly   # a runnable JAR
scala --power package report.scala --native-image  # a native binary

Dependencies use Maven coordinates; :: adds the Scala version suffix for Scala libraries.

sbt for larger projects

sbt is the standard build tool for multi-module projects and most open-source Scala libraries. Create a project from a template:

sbt new scala/scala3.g8

The layout follows the Maven convention:

my-app/
├── build.sbt
├── project/
│   ├── build.properties     # sbt version
│   └── plugins.sbt          # sbt plugins
└── src/
    ├── main/scala/          # application code
    └── test/scala/          # tests

build.sbt describes the project:

// illustrative
val scala3Version = "3.9.0"

lazy val root = project
  .in(file("."))
  .settings(
    name := "my-app",
    version := "0.1.0",
    scalaVersion := scala3Version,
    scalacOptions ++= Seq("-deprecation", "-feature", "-Wunused:all"),
    libraryDependencies ++= Seq(
      "com.lihaoyi" %% "upickle" % "4.1.0",
      "org.scalameta" %% "munit" % "1.1.0" % Test
    )
  )

Common commands — run them inside the sbt shell to keep the JVM warm:

Command Does
compile compile the code
run run the main method
test run all tests
~test re-run tests whenever a file changes
console a REPL with your project on the classpath
package build a JAR

Mill is a popular alternative build tool, with builds written as plain Scala.