Skip to main content

This page is for people who are already familiar with the Scala/JVM ecosystem.

If you just want to learn Scala CLI, head out to the Commands section.

Under the hood

Scala CLI consists of a native executable, generated by GraalVM Native Image. It runs fine on Linux and macOS with no prior requirements, and only requires the Visual C++ Redistributable Runtime on Windows. Native Image lets us build Scala CLI as a native image for each platform, and lets Scala CLI be responsive, as a command line application should be.

However, Scala CLI is still a JVM application, so it is possible to e.g. set Java properties.

Caching and incrementality

Since most of the tasks require compilation or dependency resolution under the hood, Scala CLI heavily uses caches and incrementality under the hood to provide output as quickly as possible.

But note that incremental compilation and caching are not perfect. In some cases, when there's a compilation problem and you don't think it's a problem with the code, it may be the stale state of the project - cleaning the project state might help. For this reason Scala CLI has the clean command, which invalidates local caches and forces the next compilation to be a total rebuild from a clean slate.

We provide a more in-depth overview about how caching works in the Scala CLI internals guide.


To ensure the quickest compilation, Scala CLI uses and manages the Bloop compilation server. We have a guide that describes how Scala CLI interacts with the local Bloop server and how a user can do the same. The main point to know is that Scala CLI takes care of fetching and starting Bloop if needed, so you don't have to worry about it.


Scala CLI uses Coursier to manage dependencies. It automatically downloads and unpacks a JVM if none is installed on your system, so that all its commands work fine even if a JVM isn't already installed. Scala CLI shares Coursier caches with other tools like sbt, Mill, or Metals.