Scala with Bloop and Metals
I hope we all are much familiar with building, compiling and running Scala applications with SBT.
Developers now write SBT plugins relatively quickly, especially to standardise builds across hundreds of applications in the organisation. For instance, packaging docker, fetching org-artifactory credentials, common entry scripts etc.
IMO, it is simple enough, because all we need to know is Scala and there isn’t actually a need of learning the entire SBT reference manual.
These days, I try to avoid a shell script / separate docker-compose.yml /other-language orchestrations alongside my Scala app.
I think most of them is just another new sbt task, hence, scala all the way.
I am also pretty sure, a large number of sbt plugins in open source has also made our life easy, and integrates well with things like docker, avro, git and so on and so forth.
However, not everyone is convinced yet, especially for one single reason: Speed!
Has SBT become faster these days ?
Although latest versions in SBT (as I write this, it’s 1.3.x release), is much faster than the old versions, it seems it hasn’t convinced the developers yet, especially those who have already moved from SBT to Maven (or Gradle) 1–2 years before.
Let’s learn a few technologies that exist before you decide that “SBT is not the way to go”.
I am not trying to do a performance comparison here by the way. Please try out my instructions and see if you are experiencing any positive outcomes and let me know.
Bloop is a scala build server, built to compile run, test and run Scala fast. No point re-writing what’s in this website https://scalacenter.github.io/bloop/.
But a few quick questions and answers which you might be interested:
- Is this an alternative to SBT ? No
- Is this an alternative to any other build tools ? No
- Seems like it can work together with SBT, and with other IDEs ? Yes
However, before you switch your mindsets to using Bloop through IDEs such as vs-code+metals and IntelliJ (and thereby learning it), let’s use bloop directly and get a better understanding.
We skip theory here intentionally, and let’s straight away install bloop.
To install bloop:
curl -L https://github.com/scalacenter/bloop/releases/download/v1.4.0-RC1/install.py | python
EDIT: New stable versions of bloop available. To download the latest
brew install scalacenter/bloop/bloop
For nix users, it is:
$ nix-channel --add https://nixos.org/channels/nixos-unstable
$ nix-channel --update nix-env -iA nixos-unstable.bloop$ systemctl --user start bloop
Let’s start the bloop server
Configure sbt project to work with Bloop
Almost all of you reading this blog, will have a scala project with you in your laptop. A simple scala code will have the following directory structure.
It should be a SBT project. If possible, change the SBT to some recent versions (I am using 1.3.x )
In project/plugins.sbt, add the following
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.4.0-RC1")
Now, within your projects root directory, run
$ cd myProject
$ sbt bloopInstall
In bloop, an sbt project is represented as a pair of
(sbt project, sbt configuration) and it's written to a configuration directory. The default location of this directory in your workspace is
.bloop/ (you may want to add
.bloop/ to your
Test sbt-bloop configuration
Make sure you are in the project root directory (hence cd myProject)
$ cd myProject
$ bloop projects
This should return the name of your project (in this case,
$ cd myProject
$ bloop compile myProject
If your sbt project is multi-module project,
bloop projects will return all your modules. Example
$ git clone https://github.com/zio/zio-config
$ cd zio-config
$ bloop projectsdocs
zio-config-typesafe-test$ bloop compile zio-config
Now trust me, this is much much faster than
sbt compile especially in larger projects.
Let’s try other commands
There is a decent amount of bloop commands that makes things easier for us.
$ bloop compile myProject
$ bloop run myProject //runs the only main class
$ bloop run -m com.thaj.MyMain //similar to sbt runMain command
$ bloop test myProject
All of these instructions are running faster compared to corresponding sbt tasks in my experience.
Why this set up ?
I believe, a large number of developers use intellij/other-IDEs with SBT, however rely on terminal to run
sbt run or
sbt compile for a variety of reasons. For them, by this time, the compile/test/run of the scala app is much faster already with Bloop !
For those who want to know what Metals (explained below) does under the hood, the above set up is a good learning too.
Metals: IDE integration with Bloop
For those who love IDEs, and just want to run things from IDE, this section is for you. Here we talk about
metals which you can install into IDE/text-editors.
Metals is a Scala language server with rich IDE features. The IDE features are scala focussed, and for the same reason it seems to be better than intellij presentation layer which can give false errors (the annoying red marks while my code still compiles ! that thing..) for your scala code.
Before we explain installation, keep a note that, if you are installing +using metals, you don’t need to do any of the above steps such as
bloop server, adding
sbt-bloopplugin, or run
sbt bloopInstall manually. Metals does that for you automatically.
Long story short, for anyone who didn’t like the manual life cycle management of your project with bloop, all you need is Metals.
1. Open your vs code2. Go to marketplace, and search for Metals and then install3. Open a scala project with a proper build.sbt
Once you are done with this set up, it should come up with a pop up asking to start importing the build. This implies, metals detected your scala project and is ready to start building it.
If that doesn't work for you, explicitly do
Metals: Import build . This is available in vs-code commands through Command + shift + p (if Mac), and that should start building your project.
More details are here (including troubleshooting), and it is super straight forward.
Metals & Bloop
As mentioned before, Metals will automatically start bloop server under the hood. We can test this by trying to run
bloop server again, and it will throw an error saying it is already running.
The server runs continuously. Metals also automatically does
sbt bloopInstall every-time you change your build configurations.
If metals stop working for some reason, well, you already know the details of bloop and how to communicate with it.
Trying bloop commands from terminal
All your bloop commands should work from the terminal while vs-code+metals is open. Sometimes, explicit
sbt bloopInstall and explicit
bloop compile can be much faster than
Metals: Import Build , if you are in a hurry.
Hence, consider metals as an abstraction to everything what we did before + fantastic IDE features that you need.
For those who are used to intellij keystrokes, you can install intellij keystrokes as a plugin to vs-code.
Why not Intellij + Bloop ?
Intellij’s presentation layer can be sometimes confusing, especially if you are writing GADTs in Scala, though it rarely happens.
If you are trying to have bloop features with intellij, consider this link: https://scalacenter.github.io/bloop/docs/ides/intellij
- Why Bloop ? Bloop focusses on faster compilation of scala projects, while still delegating packaging tasks to build tools such as sbt.
- Why Vs code + Metals ? Easy set up, and you get the advantage of faster compilation of bloop automatically, with a better IDE experience.
Keep a note:
1. Metals can also work with maven and gradle. However, I didn’t bother trying after I got some decent speed with Metals+sbt.
2. I am looking forward to sharing my experience with Metals + Mill (https://github.com/lihaoyi/mill)
Hope it was helpful for you. Thanks!