Library dependencies 

This page assumes you’ve already read the earlier Getting Started pages, in particular .sbt build definition, scopes, and more kinds of setting.

Library dependencies can be added in two ways:

Unmanaged dependencies 

Most people use managed dependencies instead of unmanaged. But unmanaged can be simpler when starting out.

Unmanaged dependencies work like this: add jars to lib and they will be placed on the project classpath. Not much else to it!

You can place test jars such as ScalaCheck, Specs2, and ScalaTest in lib as well.

Dependencies in lib go on all the classpaths (for compile, test, run, and console). If you wanted to change the classpath for just one of those, you would adjust dependencyClasspath in Compile or dependencyClasspath in Runtime for example.

There’s nothing to add to build.sbt to use unmanaged dependencies, though you could change the unmanagedBase key if you’d like to use a different directory rather than lib.

To use custom_lib instead of lib:

unmanagedBase := baseDirectory.value / "custom_lib"

baseDirectory is the project’s root directory, so here you’re changing unmanagedBase depending on baseDirectory using the special value method as explained in more kinds of setting.

There’s also an unmanagedJars task which lists the jars from the unmanagedBase directory. If you wanted to use multiple directories or do something else complex, you might need to replace the whole unmanagedJars task with one that does something else, e.g. empty the list for Compile configuration regardless of the files in lib directory:

unmanagedJars in Compile := Seq.empty[sbt.Attributed[]]

Managed Dependencies 

sbt uses Apache Ivy to implement managed dependencies, so if you’re familiar with Ivy or Maven, you won’t have much trouble.

The libraryDependencies key 

Most of the time, you can simply list your dependencies in the setting libraryDependencies. It’s also possible to write a Maven POM file or Ivy configuration file to externally configure your dependencies, and have sbt use those external configuration files. You can learn more about that here.

Declaring a dependency looks like this, where groupId, artifactId, and revision are strings:

libraryDependencies += groupID % artifactID % revision

or like this, where configuration can be a string or Configuration val:

libraryDependencies += groupID % artifactID % revision % configuration

libraryDependencies is declared in Keys like this:

val libraryDependencies = settingKey[Seq[ModuleID]]("Declares managed dependencies.")

The % methods create ModuleID objects from strings, then you add those ModuleID to libraryDependencies.

Of course, sbt (via Ivy) has to know where to download the module. If your module is in one of the default repositories sbt comes with, this will just work. For example, Apache Derby is in the standard Maven2 repository:

libraryDependencies += "org.apache.derby" % "derby" % ""

If you type that in build.sbt and then update, sbt should download Derby to ~/.ivy2/cache/org.apache.derby/. (By the way, update is a dependency of compile so there’s no need to manually type update most of the time.)

Of course, you can also use ++= to add a list of dependencies all at once:

libraryDependencies ++= Seq(
  groupID % artifactID % revision,
  groupID % otherID % otherRevision

In rare cases you might find reasons to use := with libraryDependencies as well.

Getting the right Scala version with %% 

If you use groupID %% artifactID % revision rather than groupID % artifactID % revision (the difference is the double %% after the groupID), sbt will add your project’s Scala version to the artifact name. This is just a shortcut. You could write this without the %%:

libraryDependencies += "org.scala-tools" % "scala-stm_2.11.1" % "0.3"

Assuming the scalaVersion for your build is 2.11.1, the following is identical (note the double %% after "org.scala-tools"):

libraryDependencies += "org.scala-tools" %% "scala-stm" % "0.3"

The idea is that many dependencies are compiled for multiple Scala versions, and you’d like to get the one that matches your project to ensure binary compatibility.

The complexity in practice is that often a dependency will work with a slightly different Scala version; but %% is not smart about that. So if the dependency is available for 2.10.1 but you’re using scalaVersion := "2.10.4", you won’t be able to use %% even though the 2.10.1 dependency likely works. If %% stops working, just go see which versions the dependency is really built for, and hardcode the one you think will work (assuming there is one).

See Cross Building for some more detail on this.

Ivy revisions 

The revision in groupID % artifactID % revision does not have to be a single fixed version. Ivy can select the latest revision of a module according to constraints you specify. Instead of a fixed revision like "1.6.1", you specify "latest.integration", "2.9.+", or "[1.0,)". See the Ivy revisions documentation for details.


Not all packages live on the same server; sbt uses the standard Maven2 repository by default. If your dependency isn’t on one of the default repositories, you’ll have to add a resolver to help Ivy find it.

To add an additional repository, use

resolvers += name at location

with the special at between two strings.

For example:

resolvers += "Sonatype OSS Snapshots" at ""

The resolvers key is defined in Keys like this:

val resolvers = settingKey[Seq[Resolver]]("The user-defined additional resolvers for automatically managed dependencies.")

The at method creates a Resolver object from two strings.

sbt can search your local Maven repository if you add it as a repository:

resolvers += "Local Maven Repository" at "file://"+Path.userHome.absolutePath+"/.m2/repository"

or, for convenience:

resolvers += Resolver.mavenLocal

See Resolvers for details on defining other types of repositories.

Overriding default resolvers 

resolvers does not contain the default resolvers; only additional ones added by your build definition.

sbt combines resolvers with some default repositories to form externalResolvers.

Therefore, to change or remove the default resolvers, you would need to override externalResolvers instead of resolvers.

Per-configuration dependencies 

Often a dependency is used by your test code (in src/test/scala, which is compiled by the Test configuration) but not your main code.

If you want a dependency to show up in the classpath only for the Test configuration and not the Compile configuration, add % "test" like this:

libraryDependencies += "org.apache.derby" % "derby" % "" % "test"

You may also use the type-safe version of Test configuration as follows:

libraryDependencies += "org.apache.derby" % "derby" % "" % Test

Now, if you type show compile:dependencyClasspath at the sbt interactive prompt, you should not see the derby jar. But if you type show test:dependencyClasspath, you should see the derby jar in the list.

Typically, test-related dependencies such as ScalaCheck, Specs2, and ScalaTest would be defined with % "test".

There are more details and tips-and-tricks related to library dependencies on this page.


sbt Reference Manual
    1. Library dependencies