Metals uses the Build Server Protocol (BSP) to communicate with build tools. Any build tool that implements the protocol should work with Metals.
There are two options for integrating Metals with a new build tool:
- via Bloop: emit Bloop JSON configuration files and use the Bloop build server. The benefit of this approach is that it's simple to implement but has the downside that compilation happens outside of your build tool.
- via custom build server: add Build Server Protocol support to your build tool. The benefit of this approach is that Metals integrates directly with your build tool, reproducing the same build environment as your current workflow. The downside of this approach is that it most likely requires more effort compared to emitting Bloop JSON files.
If you use the Bloop build server there is nothing that needs to be added in order to enable SemanticDB. Metals itself will communicate with Bloop to make sure proper options are enabled.
Otherwise, if you implement a custom build server, the SemanticDB compiler plugin is required for Metals code navigation to work. Only limited Metals features like diagnostics and code formatting will work without the SemanticDB compiler plugin enabled.
Users get a warning from Metals when the build server does not enable the SemanticDB compiler plugin. Users have an option to suppress this warning by selecting a "Don't show again" option.
Make sure to declare the compiler option
$WORKSPACE is the absolute path to the workspace root directory. By
default, the sourceroot is inferred from the working directory of the compiler
process, but it's better to explicitly declare it. If the sourceroot is
misconfigured, then Metals is unable to find the SemanticDB files created by the
We recommend you update the following compiler options when using Metals:
-Xlint: these warnings are helpful in the editor even if you don't have them enabled in your main build. Consult
scalac -Xlint:helpfor a full list of available warnings.
-Xfatal-warnings: disable this setting even if you have it enabled in your main build. Fatal warnings prevent code navigation from working when there are warnings like 'unused import'.
Consult the Bloop configuration format to learn how to emit Bloop JSON files. Once the JSON files have been generated, use "Connect to build server" server command in Metals to establish a connection with Bloop.
Consult the BSP specification to learn about the protocol in detail.
Metals automatically connects to a BSP server if the workspace root directory
.bsp/$name.json file. For example, a build tool named "Bill" will
.bsp/bill.json file with the following information.
When Metals detects a
.bsp/bill.json file in the workspace:
- it starts a new process
bill bsp, the command is derived from the
- the working directory of the process is the workspace directory.
- communication between Metals and the build server happens through standard input/output.
For a plug-and-play example of a build server, see
Bill.scala in the Metals
repository. Bill is a basic build server that is used for testing and
demonstration purposes only.
There are two available libraries to implement a BSP server:
ch.epfl.scala:bsp4j: A Java library built with Java
CompletableFuturefor async primitives and GSON for JSON serialization. This module is used by Metals and the IntelliJ Scala plugin.
ch.epfl.scala:bsp4s: A Scala library built with Monix
Observablefor async primitives and Circe for JSON for serialization. This module is used by the Bloop build server.
Both libraries are compatible with each other. For example, it's OK to implement a server with bsp4j and a client in bsp4s.
You can manually test your build server integration by running Metals with your editor of choice.
Create the following trace files to spy on incoming/outgoing JSON communication between Metals and your build tool.
Metals must re-start to pick up the trace file.
The Metals repository has infrastructure for running end-to-end integration
tests with build servers. To test your build server integration, you can to
clone the repository and write custom tests under
If there is interest, we can publish a Metals
testkit module to make it
possible to write tests outside the Metals repository.
Metals requires the following BSP endpoints to be implemented by the build server.
workspace/buildTargets: to list all the build targets in the workspace.
buildTarget/scalacOptions: to know the classpath and compiler options used to compile the project sources.
buildTarget/sources: to know what source files map to which build targets.
buildTarget/dependencySources: to support "Goto definition" for external libraries.
buildTarget/compile: to trigger compilation in a build target.
Additionally, Metals expects the server to send the following notifications:
buildTarget/publishDiagnostics: To report compile errors and warnings in the editor buffer.