Scala 3 Odyssey: Part 4 — Super Powers with VS Code and Metals

Antonel Ernest Pazargic
9 min readJun 11, 2024

--

Generated by OpenAI DALL-E

Hot, out of the oven, the 4th article in the Scala 3 Odyssey series is here.
In this article we will see how to streamline the scala development process using SBT, Visual Studio Code, Metals extension, BSP and Bloop.

Whether you missed the previous articles, or you want to refresh your memory, you can find them here:

So, let’s get started!

Introduction

I am full-speed towards preparing an efficient development environment for scala development.
In previous articles we’ve seen how to empower scala development with scala-cli, ammonite and coursier.
In this article we’ll see how to streamline the development process using:

  • SBT (Simple Build Tool)
  • Visual Studio Code
  • Metals extension
  • BSP (Build Server Protocol) and Bloop

SBT (Simple Build Tool)

Intro

In last article I’ve touched briefly the sweetness of scala development with scala-cli and ammonite.
There is no mystery that despite the powerful features offered by scala-cli, there are still some limitations.
One of the most important limitations is the lack of support for SBT plugins and multi module projects, and custom build configuration, among others.

This is where SBT comes into play.
SBT is a build tool for scala and java projects. It is a powerful tool that can be used to build, run and test scala projects.

Installation

Note:
I would like to reiterate the fact that in my articles when it comes for installation section I will provide the options only for macOS.
For Linux machined the installation is quite similar.
For Windows OS an option is to use WSL (Windows Subsystem for Linux), my preferred option. But didn’t touch Windows machines for quite some times, so don’t take my word for granted.

The installation is quite simple, my preferred ways are, in this particular order:

  • coursier

cs install sbt

  • sdkman

sdk install sbt

  • homebrew

brew install sbt

An we can check the installation via one of the following commands:
- sbt — version
- sbt about
- cs launch sbt — about (this is just for me to get acquainted with coursier a bit ;))

Noteworthy features

Having the installation done, let’s see some of the main SBT features:

  • compile and run code,
  • run tests,
  • package the project (fatjar, native with GraalVM or scala native, etc),
  • manage dependencies,
  • manage the project using a configuration file (build.sbt),
  • extend the build using plugins,
  • manage java and scala versions,
  • generate documentation,
  • execute some tasks (i.e.: run) continually with, say, sbt ~run

Usage

Let’s create a simple project using SBT, and see how to compile, run and test the code.
Also we will have a quick look at the project structure.

  • Create a new project using the following command, and choosing myapp when prompted for the project name

sbt new scala/scala3.g8

  • Change the directory to the newly created project

cd myapp

  • Compile the code

sbt compile

  • Run the code

sbt run

  • Compile tests

sbt “Test / compile”

  • Run tests

sbt test

This is how it looked like when I’ve run the commands 3, 4 and 6:

  • Package the project

sbt assembly

  • Generate the documentation,
  • Manage dependencies:
    Open build.sbt file and add the following line:

org.scalatest” %% “scalatest” % “3.2.18” % Test

so that the dependencies looks like:

libraryDependencies ++= scala.collection.Seq(
"org.scalameta" %% "munit" % "1.0.0" % Test,
"org.scalatest" %% "scalatest" % "3.2.18" % Test
)

Then we add a new simple scalatest test class in the src/test/scala directory.

import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers as ShouldMatchers

class MyScalaTestSuite extends AnyFunSuite with ShouldMatchers:
test("Basic arithmetic"):
1 + 1 should equal (2)
1 – 1 should equal (0)
1 * 1 should equal (1)
1 / 1 should equal (1)

Running the sbt test command again the added dependencies are downloaded and the tests output should look like this

## some output was removed for brevity
MySuite2:
+ example test that succeeds 0.007s
MySuite:
+ example test that succeeds 0.007s
[info] MyScalaTestSuite:
[info] — Basic arithmetic

[info] ScalaTest
[info] All tests passed.
[info] Passed: Total 3, Failed 0, Errors 0, Passed 3
[success] Total time: 4 s, completed 8 Jun 2024, 15:36:15

Project structure

Under the project root directory resides the following files and directories:

  • build.sbt: the configuration file for the project,
  • project: a directory that contains the plugins.sbt file and build.properties files,
  • src/main/scala: a directory that contains the production scala files,
  • src/test/scala: a directory containing the test scala files

There are many more features that SBT offers, but I will stop here for now, and I’ll come back with more advanced features in the future when, hopefully, I will have more experience with this tool.
Moreover, when I start working on a more complex project, like multi-module projects or projects using different plugins or custom configuration, it’ll urge me to start mastering this tool.

Visual Studio Code

Installation

Installation is quite simple, and can be done using the following options:

  • homebrew

brew install — cask visual-studio-code

  • download the installer from the official website and install it manually

If you opt for the second option, you are offered the possibility to install it on major OSes: Windows, MacOS and Linux.

Regardless the installation method, you can check the installation, on macOS, by opening the spotlight search and typing code, and the Visual Studio Code app icon should appear in the search results.

Main features

  • IntelliSense
  • Git integration
  • Integrated terminal
  • Customization
  • Extensibility via extensions
  • Debugging
  • Color and icons themes
  • Snippets
  • Code navigation
  • Refactoring

Usage

As soon as you open VS Code, you are greeted by the welcome page, where you can open a folder, open a file, or clone a repository.

The overall experience, as editor, is amazing.
And, comparing with other IDEs or editors the speed of opening a folder or a files, as well as the speed of the editor itself, is quite impressive.
But, in my personal opinion, the most important feature is the extensions support.
There are thousands of extensions available so that, practically, you may find at least one extension for almost everything you want.
Furthermore, there are tons of tutorials, medium articles or Youtube videos that showcase some of the most useful extensions, and how to use them.

I found and used extensions to develop applications in Haskell, F#, C#, Scala, Java, Python, to let alone built-in ones making the Web Development (JavaScript, TypeScript, CSS, HTML) a real pleasure.
So that, basically, no matter what was the task at hand, if there was no builtin support in VS Code, I was able to find an extension that helped me to easy the accomplishment of the task.

Installing a new extension is quite simple, you just have to open the Extensions view by clicking on the extensions icon in the Activity bar on the side of the window, or by pressing Ctrl+Shift+X, then search for the extension you want to install, and click on the install button.

Considering I am interested in scala development, I will install the following extensions:

  • Scala Metals (by scalameta),
  • Scala Syntax (by scala-lang),
  • Scala Snippets (by scala-lang),
  • Extension Pack for Java (by Microsoft)

See below how an open scala project looks like in VS Code

  • before the installation of the above mentioned extensions
  • and after they were installed

As can be seen in the first case, we lack anything that might help developing scala projects, comparing with the second case when we have scala support offered by Metals extension, turning Scala development into a delightful experience.

As highlighted in the second image, there are tons of useful scala related features, from which the below worth mentioning:

  • code highlighting,
  • compilation errors and warnings,
  • intellisense (code completion and suggestions),
  • code navigation,
  • refactoring,
  • organize imports,
  • code formatting (scalafmt.conf),
  • easy run/debug application with lenses (run, debug),
  • scala file structure (outline view),
  • commands to restart the Metals server, or to import the build

There is even a command, Metals Doctor, that helps to diagnose and fix Metals issues.

To see more about the features offered by Metals see the link in the References section.

BSP (Build Server Protocol)

BST is a protocol that allows the communication between the build server and the client (IDE, editors).
It was inspired by the LSP (Language Server Protocol), which is the protocol used by the language servers to communicate with the clients (IDEs, editors), to provide language features like code completion, code navigation, code formatting, etc.
On the documentation page this tool is pictured somewhere between the build tool (sbt, maven, gradle) on one side, and the IDE/editor (emacs, nvim, VS code, IntelliJ Idea) on the other.

According to the official documentation BSP provides endpoints for IDEs and build tools to communicate about directory layout, external dependencies, compilation, testing, running, etc.

Being a protocol it is not a tool per se, but a specification that can be implemented by build tools and IDES/editors.

More about BSP in the References section.

Bloop

Bloop is the default build server for Metals.
It implements the BSP protocol, and it is used to compile, run, test scala code.
On reference documentation page it is stated that

Bloop is a build server and CLI tool for the Scala programming language developed by the Scala Center.
Bloop has two main goals:
- Compiles, tests and runs Scala code as fast as possible,
- Integrates easily with build tools, command-line applications, editors and custom tooling

As for the bloop installation, considering Metals depends on Bloop, and uses it under the hood, in the vast majority of cases it doesn’t need to be installed separately, because it is installed automatically by Metals.
Either way, if someone really wants to install it manually, it can be done by following the instructions from the official documentation.

References

  • SBT install
  • SBT g8 templates
  • Scala Metals features
  • Build Server Protocol Specification
  • Build Server Protocol Implementations
  • Bloop installation

Closing thoughts

In this article I’ve reached the point when I have setup a solid development environment for Scala development.
I’ve started with scala-cli, then I’ve added ammonite and coursier into the mix.
And, in this article, I’ve shed a light on SBT build tool and VS Code with Metals extension.
And I’ve also briefly explored some lesser-known tools that play an important role in scala project development — BSP and Bloop.
Having this setup under our sleeves, I believe time comes to start learning more about scala, from small and simple examples emphasizing the language main features, to more complex projects requiring thinking about the architecture, design, programming paradigms.
What an extraordinary journey lays ahead of me, and I hope that you, dear reader, will join me in this journey.
If you like my articles, don’t forget to clap, share with your colleagues, friends or whomever might benefit from the information in this series.
And if you have any suggestions let me know in the comments section.

Until next time, I wish you a happy life and, why not, happy coding!

Thank you for reading and, Scala 3 rocks! 🚀🚀🚀

--

--