Published 2013-09-14.
Last modified 2019-10-17.
Time to read: 10 minutes.
Originally called the Simple Build Tool, sbt
is misnamed – it is definitely not simple! I call it the Scala Build Tool. This lecture gives you an introduction to working with this important software tool and helps you set it up for use with all of your Scala projects.
Sbt
(Scala Build Tool) is Scala’s
interactive and automated build tool, which manages your project dependencies.
Sbt
behaves like an advanced version of Maven.
While Maven can be used to build Scala projects, sbt
is almost always used instead.
sbt
build setups for large projects can be complex,
however small sbt
projects are usually simple to understand.
sbt
can build Scala and Java projects, run automated tests, generate documentation, run static code
analysis, generate front-end web assets for web applications, and many other things.
Like Maven, it fetches project dependencies automatically – including the version of the Scala compiler.
Sbt
can guarantee projects will be built in a reproducible way because it offers total control of all dependencies.
Sbt
is unique in that an sbt
project can specify the version of sbt
used to build the
project.

Because sbt
considers itself to be a dependency, the sbt
launcher will fetch
the version of sbt
specified for a project, if it has not already been fetched.
Sbt
launcher version X is bundled with sbt
version X,
and is therefore the default version of sbt
if a version is not specified for a build.
The SBT Project Setup lecture shows how to specify the
sbt
version for a project.
Sbt
is frequently run in an interactive mode while doing development.
You will learn how to use sbt
’s commands interactively in this and the other lectures on sbt
that follow.
Git is almost always used with sbt
projects.
I recommend that you
get to know the git command line,
if you are not already using it.
A Word About sbt’s Documentation
Search engines invariably provide links to out-of-date sbt
documentation, and sbt
has
changed significantly in many ways over the years.
Here is the current sbt
documentation.
Reproducible Builds
The primary function of sbt
is to support fully reproducible builds.
This is possible if the sbt
project declares all the information required to build a project within the project itself.
The necessary information includes the version of the Scala compiler and sbt
to use,
any required sbt
plug-ins, and any third-party libraries that the project depends on.
If these dependencies are all declared, an sbt
project should be able to be run by simply following these steps:
$ git clone your-project-URL
$ cd your-project
$ # Read the README
$ # Set any necessary environment variables
$ # Modify configuration files as required
$ # Start any necessary local databases
$ sbt run
Sbt
provides per-project settings and global settings.
Global settings should only specify plugins and settings that enrich your personal Scala development environment,
but which are not required to build or run any specific project.
It is bad practice to specify dependencies required to build and run specific projects in your global sbt
settings.
For example, if you use a common logging library in all your projects, don’t
specify the library in your sbt
global configuration;
instead, the specification of that dependency belongs in the project configuration of every project that uses it,
or in a separate dependency that is referenced from the build specification.
We’ll discuss popular sbt
plugins later in this lecture.
The next lecture, SBT Project Setup, discusses project-specific settings.
sbt Directory Structure
Sbt
uses a Maven-compatible directory structure for projects:
+---project +---lib +---src +---main +---java +---resources +---scala +---test +---java +---resources +---scala
As you can see, sbt
can build projects containing both Scala and Java source code. Your program and its
runtime resources are placed in the src/
directory according to the type of code (main
or
test
) and language (java
or scala
).
sbt
can also use Maven repositories of Scala and Java libraries.
Starting with v1.3.0,
released on Sep 4, 2019, sbt
uses Coursier to implement dependency management.
Older versions of sbt
used
Apache Ivy to manage dependencies,
which are placed in ~/.ivy2
by default.
Sbt
performs a two-stage build: first it compiles the project builder files
(in effect, a meta-project),
then it uses the project builder to compile and perhaps run the project code.
The project builder meta-project consists of some or all of these files:
-
If you are using
sbt
1.x, all.sbt
files in~/.sbt/1.0/
are processed; if that directory does not exist or you are using an older version ofsbt
, that directory is skipped. -
If you are using
sbt
0.13.x, all.sbt
files in~/.sbt/0.13/
are processed; if that directory does not exist or you are using an older version ofsbt
, that directory is skipped. -
All
.sbt
files in the top-level directory of your project, plusBuild.scala
if it exists in that directory. - All files in your project’s
project/
directory.
Prior to
sbt
0.13.7,
.sbt
files had to be double-spaced.
This is because the contents of .sbt
files are parsed as a domain-specific language (DSL) which is then compiled as a Scala program.
sbt
combines all of the .sbt
files together and loads them as one when it starts up,
so you can put the project information into as few or as many files as you like.
By convention, project/plugins.sbt
defines the sbt
plugins you want to make available to your project builder.
We will look at some popular plugins in a minute.
project/build.properties
contains the version of sbt
to be used with the project.
You should specify this value, so builds do not break as sbt
and Scala continue to evolve.
Here are typical contents:
sbt.version=1.3.0
You have only limited control of the version of Scala that is used by sbt
to build the meta-project.
For example, sbt
0.13.11 must use a version of Scala compatible with version 2.10.
By default, sbt
0.13.11 meta-projects use Scala 2.10.6.
Installation
You have many choices for running Scala. You can choose all of them or only one of them:
- As discussed in the Installing Scala Only section of the Installing Scala lecture, Coursier provides the easiest way to install the latest Scala command-line tools. The lecture also discusses how to install a Java development kit to power Scala.
- The remainder of the Installing Scala Only lecture discusses how to install standalone Scala compiler without using Coursier.
-
The remainder of this section is optional.
It discusses how to install
sbt
, which can be used to compile, test and and run Scala projects. You could skip down to the Checking thesbt
Version section if you don’t feel like runningsbt
from the command line, or you don’t want to spend a lot of time figuring out how to integrate editors withsbt
. The non-optional SBT Project Setup and SBT Tasks and Settings lectures that follow explainsbt
in more detail. -
The optional Setting Up IntelliJ IDEA
lecture discusses how to install and configure IntelliJ IDEA by JetBrains for use with Scala and
sbt
. IDEA installs its own versions of the Scala compiler andsbt
, based on the project settings you establish.
You can use the
official sbt
instructions
to install the sbt
launcher (which has a version of sbt
bundled with it),
or follow along below.
Mac
MacPorts and Homebrew both work.
$ brew install sbt
...or...
$ sudo port install sbt
Linux and Windows 10 Subsystem for Linux
For a Debian distro like Ubuntu, the instructions on
scala-sbt.com
work well.
The warning message is fine, at least for now.
$ echo "deb https://repo.scala-sbt.org/scalasbt/debian all main" | sudo tee /etc/apt/sources.list.d/sbt.list deb https://repo.scala-sbt.org/scalasbt/debian all main
$ echo "deb https://repo.scala-sbt.org/scalasbt/debian /" | sudo tee /etc/apt/sources.list.d/sbt_old.list
deb https://repo.scala-sbt.org/scalasbt/debian /
$ curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | sudo apt-key add Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)). OK
$ sudo apt update Hit:1 https://downloads.plex.tv/repo/deb public InRelease Hit:2 https://ca.archive.ubuntu.com/ubuntu mantic InRelease Hit:3 https://security.ubuntu.com/ubuntu mantic-security InRelease Hit:4 https://ca.archive.ubuntu.com/ubuntu mantic-updates InRelease Hit:5 https://ca.archive.ubuntu.com/ubuntu mantic-backports InRelease Hit:6 https://dl.google.com/linux/chrome/deb stable InRelease Get:7 https://scala.jfrog.io/artifactory/debian all InRelease [4,417 B] Ign:8 https://scala.jfrog.io/artifactory/debian InRelease Get:10 https://scala.jfrog.io/artifactory/debian all/main amd64 Packages [2,807 B] Get:9 https://scala.jfrog.io/artifactory/debian Release [815 B] Get:11 https://scala.jfrog.io/artifactory/debian all/main i386 Packages [2,807 B] Get:12 https://scala.jfrog.io/artifactory/debian Release.gpg [821 B] Get:13 https://scala.jfrog.io/artifactory/debian Packages [5,122 B] Fetched 16.8 kB in 2s (9,242 B/s) Reading package lists... Done Building dependency tree... Done Reading state information... Done 1 package can be upgraded. Run 'apt list --upgradable' to see it. W: https://repo.scala-sbt.org/scalasbt/debian/dists/all/InRelease: Key is stored in legacy trusted.gpg keyring (/etc/apt/trusted.gpg), see the DEPRECATION section in apt-key(8) for details. W: https://repo.scala-sbt.org/scalasbt/debian/Release.gpg: Key is stored in legacy trusted.gpg keyring (/etc/apt/trusted.gpg), see the DEPRECATION section in apt-key(8) for details. $ sudo apt install sbt Reading package lists... Done Building dependency tree... Done Reading state information... Done The following NEW packages will be installed: sbt 0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded. Need to get 20.0 kB of archives. After this operation, 50.2 kB of additional disk space will be used. Get:1 https://scala.jfrog.io/artifactory/debian all/main amd64 sbt all 1.10.1 [20.0 kB] Fetched 20.0 kB in 1s (19.0 kB/s) Selecting previously unselected package sbt. (Reading database ... 486042 files and directories currently installed.) Preparing to unpack .../archives/sbt_1.10.1_all.deb ... Unpacking sbt (1.10.1) ... Setting up sbt (1.10.1) ... Creating system group: sbt Creating system user: sbt in sbt with sbt daemon-user and shell /bin/false Processing triggers for man-db (2.11.2-3) ...
Native Windows
For native Windows, just use the .msi
installer provided on the
sbt
download site.
Checking the Currently Available sbt Version
You can check the currently installed (default) version of sbt
,
type the following at an OS prompt:
$ sbt --script-version downloading sbt launcher 1.10.1 [info] [launcher] getting org.scala-sbt sbt 1.10.1 (this may take some time)... [info] [launcher] getting Scala 2.12.19 (for sbt)... 1.10.1
To check the version of sbt
used in an sbt
project,
and the version of Scala used by sbt
:
$ sbt about [info] Loading settings for project global-plugins from idea.sbt ... [info] Loading global plugins from /home/mslinn/.sbt/1.0/plugins [info] Loading settings for project cadenzaclient-build-build from plugins.sbt ... [info] Loading project definition from /mnt/c/work/cadenzaHome/cadenzaCode/cadenzaClient/project/project [warn] There may be incompatibilities among your library dependencies; run ’evicted’ to see detailed eviction warnings. [info] Loading settings for project cadenzaclient-build from build.sbt,plugins.sbt ... [info] Loading project definition from /mnt/c/work/cadenzaHome/cadenzaCode/cadenzaClient/project [info] Loading settings for project cadenzaclient from assembly.sbt,build.sbt ... [info] Set current project to cadenzaClient (in build file:/mnt/c/work/cadenzaHome/cadenzaCode/cadenzaClient/) [info] This is sbt 1.2.8 [info] The current project is ProjectRef(uri("file:/mnt/c/work/cadenzaHome/cadenzaCode/cadenzaClient/"), "cadenzaclient") 0.1.0 [info] The current project is built against Scala 2.12.10 [info] Available Plugins [info] - coursier.sbtcoursier.CoursierPlugin [info] - coursier.sbtcoursiershared.SbtCoursierShared [info] - sbt.ScriptedPlugin [info] - sbt.plugins.CorePlugin [info] - sbt.plugins.Giter8TemplatePlugin [info] - sbt.plugins.IvyPlugin [info] - sbt.plugins.JUnitXmlReportPlugin [info] - sbt.plugins.JvmPlugin [info] - sbt.plugins.SbtPlugin [info] - sbt.plugins.SemanticdbPlugin [info] - sbtassembly.AssemblyPlugin [info] sbt, sbt plugins, and build definitions are using Scala 2.12.10
If you want to know the version of sbt
used in an existing sbt
project,
you can just examine project/build.properties
, where that value should be specified.
You can also type the following:
$ sbt sbtVersion [info] Loading settings for project global-plugins from idea.sbt ... [info] Loading global plugins from /home/mslinn/.sbt/1.0/plugins [info] Loading settings for project cadenzaclient-build-build from plugins.sbt ... [info] Loading project definition from /mnt/c/work/cadenzaHome/cadenzaCode/cadenzaClient/project/project [info] Loading settings for project cadenzaclient-build from build.sbt,plugins.sbt ... [info] Loading project definition from /mnt/c/work/cadenzaHome/cadenzaCode/cadenzaClient/project [info] Loading settings for project cadenzaclient from assembly.sbt,build.sbt ... [info] Set current project to cadenzaClient (in build file:/mnt/c/work/cadenzaHome/cadenzaCode/cadenzaClient/) [info] 1.3.3
Unfortunately, if your sbt
project fails to build,
the sbt sbtVersion
command will fail.
Unversioned Setup
Prior to sbt
0.13, there was only one global sbt
setup, in ~/.sbt/
.
Globally installed plugins were located in ~/.sbt/plugins/
.
For Windows, the directories are best referred to as %USERPROFILE%\.sbt\
and %USERPROFILE%\.sbt\project\
.
Here is my ~/.sbt/plugins/build.sbt
, set up for sbt
0.12.3 and Scala 2.10 (this is old!)
This file provides plugins for all my legacy sbt
projects.
It contains two resolvers, which I have named artifactory releases
and sbt-idea-repo
.
The name of a resolver is arbitrary; it is only there for documentation purposes.
The URL that follows tells sbt
where to look for dependencies, and the optional resolver style indicates the format of the repository.
The default resolver style is Maven, however you can see that the artifactory releases
repository uses the Ivy style.
The URL for the artifactory releases
resolver was commonly used back when sbt
0.12.3 was current.
Around that time sbt
was starting to build in standard repository URLs, but I explicitly mentioned it because
some older versions of sbt
did not know to look there.
The last release of the sbt-idea
plugin
was Aug 1, 2014, and it is no longer required or maintained.
However, this project continued to build properly as other dependencies continued to change,
because of versioned setups, discussed next.
Now that artifactoryonline.com
is gone, however, builds that reference the site will fail.
resolvers += Resolver.url("artifactory releases", url("https://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases"))(Resolver.ivyStylePatterns) resolvers += "sbt-idea-repo" at "https://mpeltonen.github.com/maven/"
sbt Versioned Setup
Globally installed plugins (those installed in ~/.sbt/plugins/
) might work with one version of
sbt
but might not work with another version of sbt
.
Because sbt
is able to automatically install any older version of sbt
as required for
the project you are currently working with, the plugins did not behave in a predictable manner.
sbt
0.13 introduced the capability for you to configure sbt
plugins differently for each
version of sbt
called for by your projects.
This means that a project that requires sbt
0.12.3, for example, can invoke an older version of a
plugin, while a newer project that uses sbt
0.13.1 can use a newer version of that same plugin –
with different settings, if desired.
To support this, versioned sbt
setup was introduced.
Two versions can be maintained.
sbt 0.13 Versioned Setup
Global settings specific to sbt
0.13.x go in ~/.sbt/0.13/
and global plugins specific to
that version of sbt
go in ~/.sbt/0.13/plugins/
.
For Windows, the directories should be specified as
%USERPROFILE%/.sbt/0.13/
and %USERPROFILE%/.sbt/0.13/project/
.
If you do not create a ~/.sbt/0.13/
directory, sbt
0.13+ runs in compatibility mode, and
issues this warning that suggests you should create the directory:
[warn] The global sbt directory is now versioned and is located at /Users/mslinn/.sbt/0.13. [warn] You are seeing this warning because there is global configuration in /Users/mslinn/.sbt but not in /Users/mslinn/.sbt/0.13.
The sentence actually says the opposite of what was intended. A better wording might be:
Your computer has no versioned global sbt directory. If you want one, create it at ~/.sbt/0.13/
Creating a Versioned Setup
If you already have ~/.sbt/
set up, and you want to create an equivalent versioned setup for
sbt
0.13, the easiest way to proceed is as follows:
$ cp -a ~/.sbt ~/.sbtTemp
$ mv ~/.sbtTemp ~/.sbt/0.13
Now edit the contents of ~/.sbt/0.13/
to suit.
My Versioned Setup
Here is my ~/.sbt/0.13/plugins/plugins.sbt
(for Windows, this file is found at %USERPROFILE%/.sbt/0.13/plugins/plugins.sbt
):
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "4.0.0") addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.6.0") addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.1.8") addSbtPlugin("com.softwaremill.clippy" % "plugin-sbt" % "0.2.5")
These plugins are described later in this lecture.
sbt 1.0 Versioned Setup
The sbt
1.0 Versioned Setup is quite similar:
Global settings specific to sbt
1.x go in ~/.sbt/1.0/
and global plugins specific to that
version of sbt
go in ~/
.
For Windows, use %USERPROFILE%/
and %USERPROFILE%/
.
The sbt-idea
plugin is no longer mentioned in this versioned setup.
Plugins
As I mentioned earlier, the sbt
launcher automatically downloads and runs an instance of the specified
version of sbt
in order to compile a project.
Plug-ins extend the functionality of sbt
.
There are hundreds of plug-ins.
Plugins are versioned and managed by sbt
in a manner similar to library dependencies.
To install a plug-in, you need to provide sbt
with:
- The fully qualified name and version of the plug-in you want to use.
- The repository that the plug-in can be found in; this is called the resolver.
For example, Scalastyle is a popular static analysis code checker for Scala.
To use the Scalastyle sbt
plugin simply add the following to your project’s project/plugins.sbt
file:
addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "0.6.0")
The above specifies that:
- The plugin’s maven group is
org.scalastyle
. - The maven id (name) of the plug-in is
scalastyle-sbt-plugin
- The version of the plugin is 0.6.0
- This plugin was written in Scala and the default name mangling scheme should be used (
%%
)
sbt
comes with some basic resolvers preconfigured, so many plugins do not need to have a resolver specified.
You do not need to add a resolver for this plugin because it resides in a well-known repository.
If you did want to add the resolver, you could specify it like this:
resolvers += "sonatype-releases" at https://oss.sonatype.org/content/repositories/releases/
Popular sbt plugins
All of these plugins could be globally specified. I do not show the installation instructions for these plugins, since they frequently change. Check the links that I provide for installation instructions.
-
plugin-sbt
– also known as Scala Clippy, is a plugin that enhances the Scala compiler’s error messages. -
scalastyle-sbt-plugin
– static code analysis for Scala. -
sbt-assembly
– Build executable jar containing all dependencies. -
sbt-dependency-graph-sugar
– Displays an SVG graph of hierarchical direct and transitive dependencies. If using Mac, install GraphViz first. If you are using Ubuntu, do the following before trying to run it:Shell$ sudo apt-get install graphviz $ mkdir -p ~/.sbt/gilt $ echo ’chromium-browser $1’ > ~/.sbt/gilt/sbt-dependency-graph-sugar-cmd
-
sbt-idea
Convertssbt
projects for use with IntelliJ IDEA; this plugin has not been required since IDEA 15. -
sbt-stats
– displays basic statistics about your project’s source code. -
sbt-updates
– Shows dependencies which have updates. Invokesbt-update
like this:Shell$ sbt dependencyUpdates
Colorized Scala REPL Output
As of Scala 2.11.3+, the Scala REPL output can be colorized. This is helpful.
- Bold blue for
val
s - Bold green for types
- Magenta for the shell prompt
If your terminal has a light-colored background, output looks like this:

If your terminal has a dark-colored background, output looks like this:

To enable colorized Scala REPL output,
define the scala.color
Java system property when invoking the
scala
compiler driver, like this:
$ scala -Dscala.color=true
For convenience, you could define a shell alias
(place this in ~/.bash_profile
for Mac; and in ~/.bashrc
for Linux):
alias scala="scala -Dscala.color=true"
To enable colorized REPL output when using sbt console
, create the following file as
~/
:
initialize ~= { _ => val ansi = System.getProperty("sbt.log.noformat", "false") != "true" if (ansi) System.setProperty("scala.color", "true") }
.sbtrc
Each line in an .sbtrc
file
is evaluated before a project is loaded.
Each sbt
project can have its own .sbtrc
file,
and you can define a global ~/.sbtrc
file in your home directory.
Examples – Clear Console Then Compile, Run or Test Affected Code
The commands from these examples cause sbt
to continually monitor your project’s source code tree,
and whenever a file changes, clear the console and then either compile, run the project or run the unit tests affected
by the change you made.
These examples share a few tricks:
- Tilde (
~
) causes whatever follows it to be performed each time a file in the project changes. - A semicolon (
;
) is equivalent to a newline. - ANSI escape codes are output.
Create a global ~/.sbtrc
containing three sbt
aliases,
which are rather like C preprocessor macros:
# Clear the screen and recompile the project each time a change is made alias cc = ~; eval "\u001B[2J\u001B[0\u003B0H"; compile # Clear the screen and rerun the project each time a change is made alias rc = ~; eval "\u001B[2J\u001B[0\u003B0H"; run # Clear the screen and only (re)run unit tests specific to the modified code alias tc = ~; eval "\u001B[2J\u001B[0\u003B0H"; testQuick
Use as follows:
$ sbt cc
Now open the courseNotes
project in an editor and make a small change to
src/
.
When you save that file, sbt
will recompile the changed project.
sbt
remains running in the background, keeping the compiler ’warm’.
Exit sbt
by typing Ctrl-D and then restart with the rc
alias:
$ sbt rc
Hello.scala
should run.
Make another small change to the file, and the program will recompile and rerun.
Exit sbt
by typing Ctrl-D and then restart with the tc
alias:
$ sbt tc
The unit tests affected by the changes you made to Hello.scala
should run.
Make another small change to the file, and the program will recompile and rerun the necessary tests.
A Better Way
These examples show useful techniques, however recent versions of sbt
provide this functionality better
via the watched.clearWhenTriggered
setting,
which will be discussed in the SBT Project Setup
lecture that follows this one.
I showed these examples to you anyway so you can understand what .sbtrc
files are for and how to work with them.
Coursier – An Alternative Maven / Ivy Fetcher
Prior to v1.3.0, sbt
was rather slow when fetching dependencies, because it used Ivy, and Ivy is slow.
Coursier
is much faster, and it has better offline support.
Coursier became standard June 18, 2019 when sbt 1.3.0 was released.

Compared to the default dependency resolution of sbt
, Coursier adds:
- Downloading of artifacts in parallel.
-
Better offline mode - one can safely work with snapshot dependencies if these are cached
(
sbt
fails if it cannot check for updates). - Non-obfuscated cache (cache structure just mimics the URL it caches).
- No global lock (no more "Waiting for
~/.ivy2/.sbt.ivy.lock
to be available").
From the command-line, Coursier also has:
- A launcher, which can launch applications distributed via Maven / Ivy repositories.
- A bootstrap generator, which can generate stripped launchers of these applications.
© Copyright 1994-2024 Michael Slinn. All rights reserved.
If you would like to request to use this copyright-protected work in any manner,
please send an email.
This website was made using Jekyll and Mike Slinn’s Jekyll Plugins.