lucidsoftware / sbt-cross

A better solution for building multiple Scala versions (cross compiling) in SBT

Version Matrix


Build Status Maven Version

A better solution for building multiple Scala versions (cross compiling) in SBT.


SBT's crossScalaVersions allows projects to compile with multiple versions of Scala.

However, crossScalaVersions is a hack that reuses projects by mutates settings. This causes problems:

  1. Performance - Each Scala version is handled sequentially (not in parallel).
  2. Subprojects - Project classpath dependencies can be tricky.
  3. Aggregation - Aggregation doesn't take into account crossScalaVersions of subprojects, hence sbt-doge.
  4. Cross paths - Very many tasks don't play nicely. E.g. if you use sbt-native-packager and +debian:packageBin, you'll build two debs on top of each other.
  5. General funniness - For example, sbt-sonatype requires extra wrangling to work with crossScalaVersions.

sbt-cross solves all by simply splitting projects: one for each version of Scala. This works with SBT's core project/task system, rather than fighting it.


Requires SBT 1.3+.

In project/plugins.sbt, add

addSbtPlugin("com.lucidchart" % "sbt-cross" % "4.0")

For the latest development version,

resolvers += Resolver.sonatypeRepo("snapshots")

addSbtPlugin("com.lucidchart" % "sbt-cross" % "master-SNAPSHOT")


Suppose there is a project pipers that uses Scala 2.11, a project drummers that uses Scala 2.12, and they depend on a project instruments, which compiles with both Scala versions.

This cannot be done with crossScalaVersions, but it can with sbt-cross.

lazy val pipers = project.dependsOn(instruments_2_11).settings(scalaVersion := "2.11.8")
lazy val drummers = project.dependsOn(instruments_2_12).settings(scalaVersion := "2.12.1")

lazy val instruments = project.cross
lazy val instruments_2_11 = instruments("2.11.8")
lazy val instruments_2_12 = instruments("2.12.1")

This defines four projects: pipers, drummers, instruments-2_11, and instruments-2_12.

SBT will concurrently compile the right ones in the right order.

  • sbt pipers/compile will compile instruments_2_11 then pipers.

  • sbt drummers/compile will compile instruments_2_12 then drummers.

  • sbt compile will compile instruments_2_11 then pipers and, in parallel, instruments_2_12 then drummers.

See examples for more.

Additional crossing

sbt-cross generalizes this approach to other any cross-compilation-like use. You can even chain cross versions. There is currently no documentation for this, but LibraryVersionAxis is an example.


We welcome issues, questions, and contributions on our GitHub project (