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
scalacommand, 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 |
|---|---|
|
The Scala compiler. |
|
Scala CLI, the runner: |
|
The sbt build tool and its native thin client. |
|
Ammonite, an enhanced REPL. |
|
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 17and Scala CLI’s--jvm///> using jvmchoices 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
scalaas the old standalone Scala 2 launcher and REPL (scalafollowed by a script name), andscalacplusscalarun by hand. In a current distributionscalais Scala CLI, soscala script.scalaandscala run script.scalaboth 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
dottylauncher or thesbt new lampepfl/dotty.g8template. 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 setupbrings in sbt, Scala CLI and Scalafmt together.