1. Introduction

SBT (Simple Build Tool, sometimes referred to as “Scala Build Tool”) offers a rich set of features for full-scale project development, from building and compiling to assembling and publishing (and more). It’s a modern build tool for Scala and Java projects, and it has become the most popular choice of Scala developers.

In this tutorial, we’ll review the standard SBT commands.

2. Installation of SBT

To start using SBT in a Scala project on Linux, macOS, or Windows, we first need to install SBT by following the steps in the documentation.

For more details, refer to the installation section in the Introduction to SBT.

3. SBT Settings, Tasks, and Commands

SBT comes with three main building blocks:

  • Settings: values that SBT reads and initializes at load time to produce the final setting values of the build. For example, an SBT project can contain settings similar to:
    organization := "com.baeldung"
    scalaVersion := "3.4.2"
    name := "scala-core"
    
  • Task: a typed declaration that is executed on every call. Task executes some action within a build. SBT has numerous tasks such as run, compile, test, assembly, and others
  • Command: similar to task, but it aims to manipulate the build definition.

Sometimes, it’s hard to distinguish between a task and a command because some commands don’t have any visible side effects, such as about and help. Nevertheless, we should remember that the principal difference between commands and tasks lies in whether they act on the build itself or not.

For example, new is a command because it creates the project and the build definition. On the other hand, assembly and package are tasks since they don’t change the build but rather create additional artifacts.

4. SBT Commands Overview

Below, we’ll explore most SBT commands tentatively classified by their purpose and review when and why we can use them. Most commands will be run in the SBT shell, denoted by the > symbol in the code snippets. Otherwise, we’ll call commands in batch mode.

4.1. General Information and Help

  1. about – prints general information about the project, including the project name, versions of SBT, Scala, the project itself, and available plugins.
    Usage: to get quick information about the SBT setup, which we’d typically need after cloning a Git repository
  2. alias – shows all available aliases for the SBT project as provided in the build.sbt file.
  3. bspReload reloads the build server protocol (BSP) configuration. BSP is the standard way of communication between SBT and IDEs. Typically, IDEs such as IntelliJ IDEA may update their state without explicit bspReload.
  4. eval evaluates the given Scala expression and prints the result and type. This is essentially a Scala console with limited capabilities embedded into SBT:
    > eval 1+2
    > [info] ans: Int = 3
    
  5. help displays help information for SBT settings, commands, and tasks (but are typically more succinct than this article):
    > help compile
    Compiles sources.
    
  6. inspect provides a detailed summary of a particular setting.
    Usage: to get an idea about a setting or get some advanced details (such as Dependencies and Reverse Dependencies of this command).
    Note: to use this command, we need first to tell SBT to switch to the subproject of interest (see project) and to pass a setting name as an argument:
    > project my_project
    > inspect libraryDependencies
    
  7. plugins lists currently available plugins for each subproject.
  8. settings prints a list of settings defined for the current project. It’s useful for viewing all the configurable settings in the project. This helps in understanding and modifying the build configuration. It doesn’t list the scopes the settings are defined in, so we’d need to use inspect for that.
  9. tasks displays the main tasks defined directly or indirectly for the current project. Note that tasks -v displays additional tasks, while tasks -V displays all tasks.

4.2. SBT Server, Project, and Session Management

  1. exit terminates the remote client or the build when called from the console, including terminating the current SBT shell in shell mode.
  2. export – runs the specified tasks and prints the equivalent command lines or other exportable information for those runs. export –last uses information from the previous execution.
  3. last prints the logging for the previous command, typically at a more verbose level.
    last prints the logging associated with the provided key (typically referring to a task – for example, last test). Logging is restricted to that particular task.
  4. lastGrep similar to last, but filters the log output using a specified pattern (see onFailure below).
  5. loadp loads the project.
  6. onFailure – allows executing a fallback action if SBT fails to execute some task or command. For example, we may want to compile the project and then open the SBT shell anyway. In that case, we should leverage onFailure. Additionally, we can pass a chain of tasks/commands, such as lastGrep, to highlight error information:
    sbt "onFailure lastGrep scala compile; shell" compile shell
    
  7. project – shows the name of the current project.
    project my_project switches to the project with the provided name (my_project):
    > project writer
    [info] set current project to writer (in build file:/Bob/bobs_project)
    
    Usage: when we need to apply some task, such as assembly, exactly for the selected project.
  8. projects lists all projects in the build, highlighting the current project:
    > projects
    [info] In file:/Bob/bobs_project
    [info]        reader
    [info]      * http
    [info]        writer
    
  9. reboot this command is equivalent to exiting SBT, restarting, and running the remaining commands, with the exception that the JVM isn’t shut down.
    If we specify dev, the command will delete the current SBT artifacts from the boot directory (~/.sbt/boot by default). This forces an update of SBT and Scala, which is useful when working with development versions of SBT.
    If we specify full, the command wipes out the boot directory before restarting.
  10. reload *– (re)*loads the project in the current directory. We’ll use this command frequently if we change the build (for example, by updating dependencies or updating .sbt files).
  11. session manipulates session settings, which are temporary settings that do not persist past the current SBT execution (that is, the current session). It can be called with arguments such as:
```bash
clear, clear-all, list, list-all, remove <range-spec>, save, save-all
```
  1. set applies the given setting (from the build.sbt) to the current project:
    *   Constructs the expression provided as an argument by compiling and loading it    *   Appends the new setting to the current project’s settings    *   Re-evaluates the build’s settings
    
```bash
set [every] <setting-expression>
```

The argument *every* is optional, but if it’s specified, the *setting* is evaluated in the current context, and the resulting value is used in every scope. This overrides the value bound to the key everywhere. As an example, we can add a new *startYear* SBT *setting* for the project as:

```bash
> set startYear:=Some(2024)
> session save-all
> reload
```

Additionally, we can specify a setting for the subproject:

```bash
> project reader
> set version:="0.1.1"
> session save
> reload
```

These operations will create a *build.sbt* file in the subproject *reader* with the new setting *version.* We should know this if we don’t want to split build definition files across the subprojects.
  1. shell opens the SBT shell.

4.3. Build

  1. < reads the lines from the given files and inserts them as commands. All empty lines and lines that start with # are ignored. If a file does not exist or is not readable, this command fails. Also, all lines from all the files are read before the commands are executed, and if any file isn’t readable, then none of the commands will be run.
  2. clearCaches clears all of SBT’s internal caches. It can help resolve issues related to cached build artifacts that may be causing unexpected behavior and build failures.
  3. new – creates a new SBT build based on the given template. Essentially, it creates a new Scala project.
    SBT provides out-of-the-box support for Giter8 templates. See also foundweekends.org/giter8/ for details. There are various templates to start a Scala project to save a lot of effort, including general projects:
    sbt new scala/scala-seed.g8
    
    and more specific projects, like cats-effect project template:
    sbt new typelevel/ce3.g8
    
  4. rebuildIdeaIndices – if the project is governed by IntelliJ Idea, it rebuilds the indices used by the IDE for faster code navigation and other IDE features (specific to IntelliJ Idea projects). It can help in some cases of build failures and incorrect code highlighting in IntelliJ IDEA.
  5. shutdown terminates the build. It closes the SBT server and the SBT shell when called from the SBT console:
    shutdown
    [info] shutting down sbt server
    
  6. ~ – Executes the specified command whenever source files change. We want SBT to notify us that the project compiles each time we change the sources:
    > ~ compile
    
    If we use ScalaJS, we may also benefit from ~ by sequential generation of the JS code from Scala code:
    > ~ fastLinkJS
    

5. Conclusion

In this article, we learned SBT commands used for reference purposes, SBT server, session, and session management, and build. This can serve as a helpful tool for the SBT commands navigation.