Developers can access Scala through an installed compiler/REPL or build tools, such as Mill or sbt. The compiler and REPL are pretty limited as neither can resolve dependencies nor easily switch between different versions of the language. The build tool approach is relatively heavy for beginners; most importantly, it means learning the basics of the build tool first, which makes learning Scala harder.
Scala’s pace of adoption accelerates whenever it becomes easier to learn. Scala 3 has introduced significant language changes, and we believe it is past time for tooling and the ecosystem to catch up with those.
The main factors that make learning easier are:
- One-click installation supporting the most popular operating systems and hardware combinations. Ideally, most users should find a way to install Scala using their preferred installation method.
- Solid defaults within the tool, so that users are not faced with too many choices too early.
- The learning curve of the tool should be minimal. People learning Scala should focus on the language, not the tools around it (there will be time to learn a build tool like sbt later)
- The tool should have rock-solid support in IDEs and tools such as scastie and notebooks.
Scala has multiple runtimes (JVM, JS, and Native), and having consistent support for all of them would make learning easier.
Existing tooling for Scala is often insufficient for rapid prototyping and issue reproduction. The key functionalities needed for those aspects are:
- Fast feedback loops
- Ability to quickly change configuration like dependencies, Scala versions or JVMs
- Flexible ways to provide configuration, sometimes the whole configuration should come directly from a command line, while at other times, self-contained examples are better
We propose that Scala CLI replaces the current ‘scala’ command as the default method for installing and learning Scala.
Because Scala CLI includes numerous installation methods native to most operating systems (such as brew or apt-get), most users will not need to install Scala using another package manager, such as coursier or sdkman. For most functionalities, there are no additional prerequisites (like having a specific version of JVM installed) and Scala CLI manages necessary dependencies.
Scala CLI is designed to balance powerful features, like dependency management, incremental compilation or support for Scala.js / Scala Native, with ease of use. Well-known and powerful tools like sbt or Mill offer everything above and more; however, both are relatively hard to learn compared to Scala CLI.
Running a Scala file with Scala CLI is as easy as running scala-cli A.scala
. Scala CLI uses native binaries, compilation server and aggressive caching to provide as fast feedback loops as possible.
Scala CLI is designed with a command-line-first approach in mind. This means that everything within Scala CLI, including dependencies, libraries or even JVMs to run a program, is configurable from the command line. This leads to super-fast feedback loops, especially when prototyping or reproducing bugs. This approach also forces a simple configuration model (key-value or key-values) without inheritance, aliasing, grouping and additional advanced features that make other tools less intuitive.
Scala CLI offers a persistent configuration in using directives
(a special type of comment) within .scala files. It may sound confusing for seasoned Scala developers, but it is pretty intuitive within the scope of projects that Scala CLI is designed for. Additionally, the in-source configuration creates self-contained examples (code and configuration) that are perfect for bug reports or education scenarios.
Scala CLI is backed by a VirtusLab team and is closely developed along with core teams of the Scala ecosystem, including those working on the Scala compiler and Metals. This provides the necessary resources to complete such an ambitious project within a reasonable time. As of now, the Scala CLI project is not even a year old.
Scala CLI has been available to the public for a few months and it is being adopted at a fast pace. We are pleased to see it getting used more often to reproduce bugs. In addition, it is being used for running examples in blog posts (e.g. here or here) or as a foundation of other tools (like snunit-cli or thingy), to name some of the use cases.
Scala CLI is still under development. It needs to be improved, especially in terms of IDE integration, particularly Intellij. This is one of our main focus points. Currently, scala-cli behaves differently from the current scala
command. For example, running just scala
starts an empty REPL session when scala-cli
will just print the help message. However, given that scala-cli has much a broader scope than the current scala
command, matching the exact behaviour of the current scala
command is likely to cause more harm than good in the long run.
The use of Scala CLI doesn’t stop at prototyping and learning. Scala CLI turns Scala into a proper scripting language with support for shebang, piping input and more (see here). Scala CLI can be used to build small projects and features like packaging for docker images or self-contained executables that are really useful in such a context. In the future, it will allow for the creation and publishing of micro-libraries.
Too many features?
Scala CLI contains many valuable features that may seem too much for just a scala
command. To make Scala CLI into a battery-included tool and at the same time keep scala simple and accessible, we decided to implement a mechanism to limit the accessible commands and options depending on whether Scala CLI is run as scala
or scala-cli (or maybe even a shorter form like scl). In this way, we can experiment with new features and, at the same time, keep the scala command accessible. While compile
, run
and repl
are pretty obvious choices, we suggest that format
, test
and clean
should also be included in the new scala
command. Option-wise, we do not think any of the existing options for the commands above should be disabled when running the new scala
command.
As Scala CLI would install multiple binaries anyway (scala and scala-cli), we may consider including coursier
to provide users with an option to install other tools from the Scala ecosystem, such as sbt or scalafix.
Conclusion
We learned a lot during the development of Scala CLI. We are now prepared to discuss whether Scala CLI should become a scala
command and, if so, what the scope of this new ‘scala’ command should be. This post only briefly touches on what Scala CLI is and can do, and we recommend you to check out our documentation to learn more.
We do not fear criticism, yet we highly recommend you try out Scala CLI before commenting, as we have seen many cases where people who were initially sceptical about the project changed their opinion after using it for a few days, for a use-case it was designed for