Installing Scala

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

The reference material consulted while preparing these pages is listed in the section bibliography.

This page is written against Scala 3.10.0 (released 2026-10-12, the current Scala Next line) with Scala CLI 1.17.1 on JDK 26. Every command whose output is shown below was run on that setup on 2026-10-15; commands that install software (Coursier, Homebrew, SDKMAN!, the packages) are quoted from the official documentation and are not run here, because the examples in this section share one pre-extracted Scala distribution. Scala 3.10 needs JDK 17 or later; the 3.9 LTS line has the same floor, and only the 3.3 LTS line still runs on JDK 8 and 11. If you only want to try the language, you can skip this page and use Scastie in the browser, described on REPL, Worksheets & Scastie; the next page, Hello World & @main Methods, assumes the setup from this one. Which line to pick (3.10 or 3.9 LTS) is explained on Getting Started & Versions. For comparison, the equivalent steps for another JVM language are on Groovy Getting Started.

What you need and what "installing Scala" means

Scala is not a single download. To compile, run, test and package a project you need a JDK plus a handful of command-line tools, and the official docs define "installing Scala" as installing all of them:

  • a JDK, because Scala’s primary platform is the JVM (Scala.js and Scala Native are separate targets, covered later in this section);

  • the Scala compiler, scalac;

  • the Scala runner, the scala command, which since the 3.5 line is Scala CLI under the hood (it compiles, runs, tests, opens a REPL and packages code);

  • a build tool for larger projects, usually sbt (Mill is the other common choice);

  • optionally a formatter (Scalafmt) and a language server (Metals) for your editor (see IDEs & Tools for the IDEs and editors).

The tool the Scala team recommends for installing all of this is Coursier, whose command is cs. It also manages the JVM for you, so on a machine that has no Java at all, one command is enough. Everything below is an alternative way to reach the same state, and you only need one of them.

Install with Coursier (cs setup)

The official installation page documents one command per platform. On macOS, with Homebrew:

brew install coursier && coursier setup

On macOS without Homebrew (Apple Silicon shown; the x86-64 build lives in the Coursier release assets instead) and on Linux (x86-64 shown), the pattern is to download the single-file launcher, make it executable and run its setup command:

# macOS on Apple Silicon: download, decompress, remove the quarantine flag, run setup
curl -fL https://github.com/VirtusLab/coursier-m1/releases/latest/download/cs-aarch64-apple-darwin.gz | gzip -d > cs && chmod +x cs && (xattr -d com.apple.quarantine cs || true) && ./cs setup

# Linux on x86-64
curl -fL https://github.com/coursier/coursier/releases/latest/download/cs-x86_64-pc-linux.gz | gzip -d > cs && chmod +x cs && ./cs setup

On Windows you download and run the installer executable linked from the same page. The exact, current commands for every platform, including Linux on ARM64, are on the official page, and are worth copying from there because release URLs move between organizations over time (the Apple Silicon build above comes from the VirtusLab fork). Piping a download into a shell is a trust decision: read what you are running, and prefer your package manager when it carries the tool.

cs setup asks a few questions, then installs a JVM if there is none, puts the tools on your PATH and may modify your shell profile. You may need to restart the terminal, log out or reboot before the new PATH is visible. The tools it installs:

Command What it is

scalac

The Scala compiler.

scala, scala-cli

Scala CLI, the runner: run, compile, test, repl, package, fmt and more.

sbt, sbtn

The sbt build tool and its native thin client.

amm

Ammonite, an enhanced REPL.

scalafmt

The Scalafmt code formatter.

Two details of cs setup are easy to miss. It installs the Scala 3 compiler and runner by default; because real projects choose their Scala version in the build, the globally installed one rarely matters. And Coursier can launch any other version without installing it, for example cs launch scala:2.13.18 or cs launch scalac:2.13.18; to make Scala 2 the default, cs install scala:2.13.18 scalac:2.13.18. The Coursier documentation covers the installer itself, including offline and CI-friendly variants.

Check the installation

The official check is scala -version. Here is the real output of the distribution used to run the examples on this page:

scala -version
Scala code runner version: 1.17.1
Scala version (default): 3.10.0

Note that the first line is the version of the runner (Scala CLI), not of the language: the two numbers move independently. The version subcommand prints the same information and can print each half on its own, which is handy in scripts:

scala version --cli-version
scala version --scala-version
1.17.1
3.10.0

The compiler has its own banner:

scalac -version
Scala compiler version 3.10.0 -- Copyright 2002-2026, LAMP/EPFL

The version shown by scala -version is only the default. A program can ask for another one, and it can also ask the running program which Scala and JDK it actually got. This complete program checks both:

//> using scala 3.10.0

@main def check(): Unit =
  println(s"Scala ${scala.util.Properties.versionNumberString} on JDK ${Runtime.version().feature()}")
  println(s"java.vendor = ${System.getProperty("java.vendor")}")
  assert(scala.util.Properties.versionNumberString == "3.10.0")

Run it with scala run check.scala:

Compiling project (Scala 3.10.0, JVM (26))
Compiled project (Scala 3.10.0, JVM (26))
Scala 3.10.0 on JDK 26
java.vendor = Oracle Corporation

The Compiling project (Scala 3.10.0, JVM (26)) line is the quickest way to see which Scala version and which JVM a run used.

Choosing a JDK

Scala runs on the JVM, so the choice of JDK matters more than it does for most languages. The rules from the official JDK-compatibility page, as checked on 2026-10-15:

  • Scala 3 versions from 3.3 LTS through 3.7 support JDK 8 and above. Scala 3 starting with 3.8 requires JDK 17 or later, so 3.8, 3.9 LTS and 3.10 do not run on JDK 8 or 11.

  • JDK 17, 21 and 25 (all LTS releases) are all good choices for both compiling and running. Because the JVM is backward compatible, running on a newer JVM than the one you compiled on is normally safe.

  • Minimum Scala versions per JDK for the lines in this section: JDK 17 needs 3.3.0 on the 3.3 LTS line and 3.9.0 on the 3.9 LTS line; JDK 21 needs 3.3.1 (3.3 LTS) or 3.9.0; JDK 25 needs 3.3.7 or 3.9.0; JDK 26 needs 3.3.8, 3.9.0 or 3.8.0; JDK 27 is listed with 3.10.0. Using the latest patch version of the line you picked is always recommended.

  • Tool floors for JDK 25: Scala CLI 1.10.0, sbt 1.9.0 and Mill 1.0.0 are the minimum working versions, and some tools print warnings at startup on JDK 25 and later.

  • Non-LTS JDKs are supported on a best-effort basis: they are not release blockers for the Scala team.

  • To compile on a new JDK but stay compatible with an older one, pass --release (for example --release 17) so the compiler does not use newer JDK APIs. scalac -release 17 and Scala CLI’s --jvm///> using jvm choices are the usual knobs.

The practical advice is to use one JDK 21 or 25 distribution (Temurin and Zulu are what the Scala team tests with) and leave it there. The distribution used to write this section is Oracle’s JDK 26, which works but is a non-LTS release.

JDK 3.3 LTS 3.9 LTS Scala Next

17 (LTS)

3.3.0

3.9.0

3.4.0

21 (LTS)

3.3.1

3.9.0

3.4.0

25 (LTS)

3.3.7

3.9.0

3.7.1

26

3.3.8

3.9.0

3.8.0

27

 — 

 — 

3.10.0

Scala CLI can also provision a JVM by itself with //> using jvm 21 or the --jvm option, which is how many scripts pin the Java version without touching the system installation. That is a download at first use, so it is quoted here rather than run.

Other ways to install

Coursier is the recommended path, but it is not the only one. The Scala 3.10 release notes state that a version manager such as Coursier, SDKMAN! or Homebrew remains the recommended way, because they make upgrades and switching between versions easy.

Homebrew (macOS and Linux). The Scala installation page uses Homebrew to install Coursier and then lets Coursier do the rest, as shown above. Homebrew also has formulae named coursier and scala. The page on scala-lang.org spells the first command slightly differently (brew install coursier/formulas/coursier && cs setup), which is the same thing with the tap named explicitly. Check brew info scala for the version that formula actually installs, since formulae can trail the newest release.

SDKMAN! installs and switches between JDKs and Scala distributions in one tool, which is convenient when you work on several projects with different baselines:

sdk list java        # JDK candidates and identifiers on your platform
sdk install scala    # default Scala candidate known to SDKMAN!
sdk list scala       # every version available
sdk use scala 3.9.0  # switch for the current shell (use a version from the list)

Distribution archives and installers. Every release page on https://www.scala-lang.org/download/all.html offers the distribution as an archive for Linux and macOS and an installer for Windows. Unpack it somewhere and add its bin directory to your PATH; the directory holds scala, scalac and scaladoc plus their .bat twins for Windows. This is the layout of the distribution used for the examples here.

Debian and RPM packages (new in 3.10). Scala 3.10 ships the distribution as .deb and .rpm packages, published as GitHub release assets next to the existing archives, so Debian and Ubuntu systems can use apt or dpkg, and Fedora and RHEL-family systems dnf or rpm, when that suits your environment better than a version manager. Download the asset from the release page of the version you want and install it with your package manager (file names are in the release assets):

sudo apt install ./<scala-package>.deb      # Debian and Ubuntu
sudo dnf install ./<scala-package>.rpm      # Fedora and RHEL family

These packages do not work on 3.9 LTS or earlier, because they first appear in 3.10.0. Treat them as the right tool for servers and containers where a system package is preferred, and a version manager as the right tool for development machines.

Scala CLI on its own. If you already have a JDK, installing only Scala CLI is enough to compile, run and test a project, including choosing the Scala version per file. Its installation page lists the supported installers. The scala command in a 3.10 distribution is the same program as Scala CLI, so installing the distribution already gives you both.

Which Scala version does a project use?

Installing a "default" Scala is only half of the story: projects pick their own version, and the global one is just the fallback. In Scala CLI the pin is a using directive at the top of a file, before any code, and it contributes to the whole compilation scope:

//> using scala 3.10.0

The directive accepts a complete version, a prefix, or more than one Scala version (to cross-build):

//> using scala 3.9.0
//> using scala 3.10
//> using scala 2.13
//> using scala 2.13.6 2.12.16

The second line is a prefix, so it resolves to the newest 3.10.x that exists. That is checked here: the program below declares //> using scala 3.10, and the run first downloads Maven Central’s version listing and then compiles with the newest 3.10 release.

//> using scala 3.10

@main def pre(): Unit = println(scala.util.Properties.versionNumberString)
Downloading https://repo1.maven.org/maven2/org/scala-lang/scala3-library_3/maven-metadata.xml
Downloaded https://repo1.maven.org/maven2/org/scala-lang/scala3-library_3/maven-metadata.xml
Compiling project (Scala 3.10.0, JVM (26))
Compiled project (Scala 3.10.0, JVM (26))
3.10.0

Scala CLI also accepts version tags that follow the LTS lines. lts (and 3.lts) stands for the newest release of the current LTS line, and <prefix>.lts pins one LTS series, such as 3.9.lts or 3.3.lts; a prefix that is not an LTS line, such as 3.7.lts, is not recognised. Since Scala CLI 1.17.0 lts points at 3.9 LTS; before that it meant 3.3 LTS.

//> using scala lts

@main def lts(): Unit = println(scala.util.Properties.versionNumberString)
3.9.0

Run with the scala 3.10.0 launcher (Scala CLI 1.17.1), the program printed 3.9.0. The same file with //> using scala 3.3.lts, or a file with no directive run with -S 3.3.lts, compiled with Scala 3.3.8: the class path printed by --print-class-path held scala3-library_3-3.3.8.jar. (On 3.3 the program itself prints 2.13.18, because there versionNumberString reports the Scala 2.13 standard library that Scala 3.3 uses.) -S lts and -S 3.9.lts gave 3.9.0 too. Like a prefix, a tag moves with each release, so it is for scripts rather than reproducible builds.

A prefix is convenient in scratch scripts, but not for reproducible builds: for anything shared, write the full version. The same choice can be made on the command line without editing a file, with -S (alias of --scala-version):

scala run hello.scala -S 3.9.0

(Not run here, because it would download the 3.9.0 compiler. Use it on a file that has no //> using scala line; do not combine the two without checking the Compiling project (Scala ...) line to see which one won.)

The help text of this runner says "Set the Scala version (3.9.0 by default)" for that option while the launcher’s own default is 3.10.0, because the option’s text comes from the bundled Scala CLI release. Trust scala -version for the version the scala command will use, and trust the Compiling project (Scala ...) line for the version a particular run used.

In sbt the equivalent pin is a setting in build.sbt, and the sbt launcher downloads that compiler itself, which is why a globally installed Scala hardly matters for an sbt project:

ThisBuild / scalaVersion := "3.10.0"

Pick the line deliberately. Scala Next (3.10.x today) gets the newest language features and fixes; the 3.9 LTS line is the one the download page advises for publishing libraries, and the 3.3 LTS line (3.3.8 at the check date) still supports JDK 8 and 11. The details are on Getting Started & Versions.

Nightly builds

Scala 3 and Scala 2 publish nightly versions so that you can try upcoming changes. Scala 3 nightlies live in the repo.scala-lang.org repository (older ones, up to August 2025, are also on Maven Central), and a nightly can be used like any other version once you know its full version number. With Scala CLI there is no extra configuration, because the nightly repository is built in from Scala CLI 1.9.0 (or the scala command of Scala 3.7.3 and later):

scala -e 'println("Hello")' -S 3.nightly
scala -e 'println("Hello")' -S 3.3.nightly
scala -e 'println("Hello")' -S 2.13.nightly

or in a file:

//> using scala 3.nightly

The qualifiers 3.nightly, 3.3.nightly, 2.nightly, 2.13.nightly and 2.12.nightly are documented; a plain -S 3.nightly selects the newest Scala 3 nightly. To find the exact number, open https://nightly.scala-lang.org and read the version in the upper left corner. These commands are quoted from the documentation and not run here, because they would download a compiler. With sbt, add resolvers += Resolver.scalaNightlyRepository and use sbt 1.11.5 or newer.

Nightlies are unreleased builds. Use them to test that your library survives an upcoming release (this is what the community build does), and never for production.

Where the books are outdated

Older books and blog posts that you will meet while learning install Scala in ways that no longer apply:

  • They show scala as the old standalone Scala 2 launcher and REPL (scala followed by a script name), and scalac plus scala run by hand. In a current distribution scala is Scala CLI, so scala script.scala and scala run script.scala both work, but the options are Scala CLI’s.

  • They install through a manual download and SCALA_HOME. Neither is needed with Coursier, SDKMAN! or Homebrew.

  • They say "Scala 3 is Dotty" and tell you to use the dotty launcher or the sbt new lampepfl/dotty.g8 template. Both belong to the 2018-2021 era; use Scala 3 directly.

  • They assume JDK 8. Scala 3.8 and later need JDK 17 or later.

  • They treat the installer as separate from the build tool. Today cs setup brings in sbt, Scala CLI and Scalafmt together.