Skip to main content

Release notes


Make .scalafmt.conf optional when running the fmt command

Scala CLI can now run the fmt command without a .scalafmt.conf file present. Previously, if such a file was absent, a Scalafmt requires explicitly specified version. error was raised while using the fmt command.

The Scala CLI fmt command now supports passing the scalafmt version and dialect directly from the command line, using the --scalafmt-dialect and --scalafmt-version options respectively:

scala-cli fmt --scalafmt-dialect scala3 --scalafmt-version 3.5.8

Either of those (or both) can be skipped, which will make Scala CLI infer a default value.

The configuration used can be saved in the workspace by passing the --save-scalafmt-conf option.

Added in #1192 by wleczny

Define output option for package command with using directives

It is now possible to pass the output option of the package command with using directives instead of passing it directly from bash.

Added in #1213 by wleczny

Add support for running multiple snippets of the same kind

Scala CLI now allows to pass multiple snippets of the same kind.

It was previously possible to mix different kinds (so to pass a Java snippet alongside a Scala one), but not for example 2 separate Scala snippets. That limitation no longer applies.

When passed this way, each snippet is then treated as a separate input by Scala CLI.

$ scala-cli --scala-snippet '@main def main() = println(Messages.hello)' --scala-snippet 'object Messages { def hello = "Hello" }'

Added in #1182 by Gedochao

Add bloop sub-command

Scala CLI now has a (hidden for now) bloop sub-command, that runs a command using the Scala CLI Bloop server (while the mainline Bloop bloop CLI uses its default Bloop server). This is handy when debugging things on Scala CLI for example, allowing one to manually run scala-cli bloop projects or scala-cli bloop compile.

Added in #1199 by alexarchambault

Make main class optional in preamble-less assemblies

It is now allowed to generate an assembly, even for code that has no main class, when --preamble=false is passed. This can be useful for libraries, if users want to pass the assembly to tools such as proguard. This also accepts a (hidden) --main-class-in-manifest=false option if users want not only no preamble, but also no mention of main class in the assembly manifest (META-INF/MANIFEST.MF in the assembly JAR). The latter option is useful for tools, such as the hadoop jar command, that behave differently depending on the presence or not of a main class in the manifest.

Added in #1200 by alexarchambault

Important fixes & enhancements

Prevent erroneous using directives from blocking the initial run of BSP

Up till now, running the setup-ide sub-command on sources containing using directives with syntax errors or pointing to dependencies which could not be fetched would create a BSP setup which could not be imported correctly by IDEs. This is no longer the case and such a BSP connection should now import correctly, so that it's possible to fix the faulty code within the comfort of one's IDE of choice.

This fixes #1097

Added in #1195 by Gedochao

Work in progress

Allow to globally turn actionable diagnostics on or off

It is now possible to globally enable or disable actionable diagnostics using the config sub-command.

The relevant configuration is under the actions key.

$ scala-cli config actions true

Added in #1193 by lwronski

Other changes


Build and internal changes


Full Changelog:


Initial support for importing other sources via using directives

It is now possible to add sources to a Scala CLI project from a source file, with using file directives:

//> using file "Other.scala"
//> using file "extra/"

Note that several sources can be specified in a single directive

//> using file "Other.scala" "extra/"

Added in #1157 by lwronski.

Add dependency update sub-command

Scala CLI can now update dependencies in user projects, using the dependency-update sub-command, like

scala-cli dependency-update --all .

When updates are available, this sub-command asks whether to update each of those, right where these dependencies are defined.

Added in #1055 by lwronski.

Running snippets passed as arguments

Scala CLI can now run Scala or Java code passed on the command-line, via -e / --script-snippet / --scala-snippet / --java-snippet:

$ scala-cli -e 'println("Hello")'

$ scala-cli --script-snippet 'println("Hello")'

$ scala-cli --scala-snippet '@main def run() = println("Hello")'

$ scala-cli --java-snippet 'public class Main { public static void main(String[] args) { System.out.println("Hello"); } }'

These options are meant to be substitutes to the -e option of the scala script that ships in scalac archives.

Added in #1166 by Gedochao.

Uninstall instructions and uninstall sub-command

Uninstalling Scala CLI is now documented in the main installation page, right after the installation instructions. In particular, when installed via the installation script, Scala CLI can be uninstalled via a newly added uninstall sub-command.

Added in #1122 and #1152 by wleczny.

Important fixes & enhancements

ES modules

Scala CLI now supports the ES Scala.js module kind, that can be enabled via a //> using jsModuleKind "esmodule" directive, allowing to import other ES modules in particular.

Added in #1142 by hugo-vrijswijk.

Putting Java options in assemblies, launchers, and docker images, in package sub-command

Passing --java-opt and --java-prop options to the package sub-command is now allowed. The passed options are hard-coded in the generated assemblies or launchers, and in docker images.

Added in #1167 by wleczny.

--command and --scratch-dir options in run sub-command

The run sub-command can now print the command it would have run, rather than running it. This can be useful for debugging purposes, or if users want to manually tweak commands right before they are run. Pass --command to run to enable it. This prints one argument per line, for easier automated processing:

$ scala-cli run --command -e 'println("Hello")' --runner=false

When run relies on temporary files (when Scala.js is used for example), one can pass a temporary directory via --scratch-dir, so that temporary files are kept even when scala-cli doesn't run anymore:

$ scala-cli run --command -e 'println("Hello")' --js --runner=false --scratch-dir ./tmp

Added in #1163 by by alexarchambault.

Don't put Scala CLI internal modules in packages

Scala CLI doesn't put anymore its stubs module and its "runner" module in generated packages, in the package sub-command.

Fixed in #1161 by alexarchambault.

Don't write preambles in generated assemblies in the package sub-command

Passing --preamble=false to scala-cli package --assembly makes it generate assemblies without a shell preamble. As a consequence, these assemblies cannot be made executable, but these look more like "standard" JARs, which is required in some contexts.

Fixed in #1161 by alexarchambault.

Don't put some dependencies in generated assemblies in the package sub-command

Some dependencies, alongside all their transitive dependencies, can be excluded from the generated assemblies. Pass --provided org:name to scala-cli package --assembly to remove a dependency, like

$ scala-cli package SparkJob.scala --assembly --provided org.apache.spark::spark-sql

Note that unlike "provided" dependencies in sbt, and compile-time dependencies in Mill, all transitive dependencies are excluded from the assembly. In the Spark example above, for example, as spark-sql depends on scala-library (the Scala standard library), the latter gets excluded from the assembly too (which works fine in the context of Spark jobs).

Fixed in #1161 by alexarchambault.

In progress

Experimental Spark capabilities

The package sub-command now accepts a --spark option, to generate assemblies for Spark jobs, ready to be passed to spark-submit. This option is hidden (not printed in scala-cli package --help, only in --help-full), and should be considered experimental.

See this document for more details about these experimental Spark features.

Added in #1086 by alexarchambault.

Other changes


Build and internal changes


New Contributors

Full Changelog:


--list-main-classes for publish & package

publish and package sub-commands now support the --list-main-classes option, which allows to list all the available main classes. Previously it was only available in the run command.

Added in #1118 by Gedochao

Important fixes & enhancements

fmt options improvement

Added missing documentation on how to pass native scalafmt options in the fmt sub-command with the -F option.

$ scala-cli fmt -F --version
scalafmt 3.5.2

Additionally, a couple of scalafmt's native options received aliases in Scala CLI:

--respect-project-filters is an alias for -F --respect-project-filters. Because of the way sources are passed by Scala CLI to scalafmt under the hood, we now turn it on by default to respect any project.excludePaths settings in the user's .scalafmt.conf.
It can be disabled by passing --respect-project-filters=false to revert to previous behaviour. This addresses #1121

--scalafmt-help is an alias for -F --help. It shows the --help output from scalafmt, which might prove as helpful reference when in need of using native scalafmt options with -F.

Added in #1135 by Gedochao

Include libsodium.dll on Windows

Static linking of libsodium in Windows launcher has been fixed. This addresses #1114

Added in #1115 by alexarchambault

Force interactive mode for update command

Interactive mode for update sub-command is now enabled by default.

Added in #1100 by lwronski

In progress

Better BSP support for Scala scripts

Other changes

Documentation PRs

Build and internal changes


Full Changelog:


--list-main-classes option for the run command

You can pass the option --list-main-classes to the run command to list all the available main classes, including scripts.

$ scala-cli . --list-main-classes
Hello scripts.AnotherScript_sc scripts.Script_sc

Added in #1095 by Gedochao

Add config command

The config sub-command allows to get and set various configuration values, intended for use by other Scala CLI sub-commands.

This feature has been added in preparation for the publish command, stay tuned for future announcements.

Added in #1056 by alexarchambault

Prioritise non-script main classes

When trying to run a directory containing scripts and just a single non-script main class, the non-script main class will now be prioritised and run by default.

$ scala-cli .
Running Hello. Also detected script main classes: scripts.AnotherScript_sc, scripts.Script_sc
You can run any one of them by passing option --main-class, i.e. --main-class scripts.AnotherScript_sc
All available main classes can always be listed by passing option --list-main-classes
Hello world

Changed in #1095 by Gedochao

Important bugfixes

Accept latest Scala versions despite stale Scala version listings in cache

Scala CLI uses version listings from Maven Central to check if a Scala version is valid. When new Scala versions are released, users could sometimes have stale version listings in their Coursier cache for a short period of time (the Coursier cache TTL, which is 24 hours by default). This prevented these users to use new Scala versions during that time. To work around that, Scala CLI now tries to re-download version listings when they don't have the requested Scala version. This addresses #1090

Fixed in #1096 by lwronski

Bloop now uses JAVA_HOME by default

Bloop should now pick up the JDK available in JAVA_HOME. It was formerly necessary to pass --bloop-jvm system explicitly. This addresses #1102

Fixed in #1084 by lwronski

The -coverage-out option now accepts relative paths

Scala CLI now correctly processes relative paths when passed to the -coverage-out option. Formerly, the scoverage.coverage file would not be properly generated when a relative path was passed. This addresses #1072

Fixed in #1080 by lwronski

Other changes

Documentation PRs


  • Add suffix to project name which contains virtual files by lwronski in #1070

Build and internal changes

Full Changelog:

Older versions

The release notes for all the past versions of Scala CLI can be viewed on our releases page on GitHub.