
Migrating Your Scala 2.13 Project to Scala 3: A Step-by-Step Guide
Are you planning to upgrade your Scala 2.13 project to Scala 3? With Scala 3 offering an improved type system, better syntax, and enhanced Java interoperability, the migration is well worth it. However, transitioning between major versions can be challenging. In this guide, we’ll walk you through the migration process using the Scala 3 Migrate Plugin.
By following these steps, you can ensure a smooth upgrade with minimal disruptions.
Prerequisites
Before starting, ensure that your development environment meets the following requirements:
- SBT version: 1.5 or later
- Java version: 8 or later
- Scala version: 2.13.5 or later
Once these are set up, you’re ready to begin the migration process.
Step 1: Install the Scala 3 Migrate Plugin
To use the migration tool, you need to add the Scala 3 Migrate Plugin to your plugins.sbt file:
addSbtPlugin(“ch.epfl.scala” % “sbt-scala3-migrate” % “0.5.1”)
After adding the plugin, reload your SBT project.
Step 2: Select a Module for Migration
If your project has multiple modules, it’s recommended to migrate them one at a time. Start with a small module that has minimal dependencies to simplify debugging and troubleshooting.
Step 3: Migrate Dependencies
Run the following command to check which dependencies need updates:
migrate-libs projectId
This command scans your dependencies and suggests compatible versions for Scala 3. For example, consider the following build.sbt snippet:
val akkaVersion = “2.6.5”
lazy val core = project
.in(file(“core”))
.settings(
scalaVersion := “2.13.6”,
libraryDependencies ++= Seq(
“com.typesafe.akka” %% “akka-stream” % akkaVersion
)
)
After running migrate-libs, you may get an output suggesting updates like:
com.typesafe.akka:akka-stream:2.6.5 -> 2.6.19 (valid)
Update your build.sbt accordingly.
Step 4: Update Compiler Options
Scala 3 introduces some changes to compiler options (scalacOptions). To check for outdated options, run:
migrate-scalacOptions projectId
For example, if your project has:
scalacOptions ++= Seq(“-explaintypes”, “-Wunused”)
Scala 3 requires an update:
scalacOptions ++= Seq(“-explain-types”)
Apply these changes before proceeding.
Step 5: Fix Syntax Incompatibilities
Scala 3 introduces stricter syntax rules. To fix syntax issues automatically, run:
migrate-syntax projectId
This command will apply Scalafix rules to update deprecated syntax, such as:
Example 1: Procedure Syntax
Before (Scala 2.13):
def sayHello() {
println(“Hello!”)
}
After running migrate-syntax, it updates to:
def sayHello(): Unit = {
println(“Hello!”)
}
Example 2: Eta Expansion
Before (Scala 2.13):
val add = (x: Int, y: Int) => x + y
val sum = add
After:
val add: (Int, Int) => Int = (x, y) => x + y
val sum = add.tupled
Review the changes and manually adjust where necessary.
Step 6: Final Migration Step
Once dependencies and syntax updates are complete, finalize the migration by running:
migrate projectId
This step attempts to compile your code with Scala 3, adding inferred types and adjusting implicit arguments where needed.
If errors occur, manually review them and apply necessary fixes.
Step 7: Update Scala Version
After successful migration, update your Scala version in build.sbt:
scalaVersion := “3.3.0”
Then remove the Scala 3 Migrate Plugin from plugins.sbt and test your project thoroughly.
Conclusion
Migrating from Scala 2.13 to Scala 3 can seem daunting, but the Scala 3 Migrate Plugin streamlines the process by handling dependencies, syntax changes, and compiler options automatically. By following this step-by-step guide, you can ensure a smooth transition and leverage the latest features of Scala 3.
Start migrating today and take advantage of Scala 3’s enhanced capabilities!