Skip to main content

Basics

Scala CLI is a command line tool that executes a given command on the inputs it’s provided with a given configuration to produce a result.

The most important commands are:

  • compile compiles your code (excluding tests)
  • run runs your code using the provided arguments (it’s also used when no other command is provided)
  • test compiles and runs the tests defined in your code
  • package packages your code into a jar or other format
  • repl / console runs the interactive Scala shell
  • fmt formats your code

When Scala CLI is run without any commands, it defaults to the run command, so
scala-cli a.scala runs your a.scala file.

Input formats

The scala-cli CLI commands accept input in a number of ways, most notably:

  • as source files
  • as one or several directories that contain source files
  • as URLs, pointing to sources
  • by processing source code via piping or process substitution

Note that all of these input formats can used alongside each other.

Source files

Scala CLI accepts the following types of source code:

  • .scala files, containing Scala code
  • .sc files, containing Scala scripts (see more in Scripts guide)
  • .java files, containing Java code

This example shows the simplest input format. First, create a source file:

Hello.scala
object Hello {
def main(args: Array[String]): Unit =
println("Hello from Scala")
}

The run it by passing it to scala-cli:

scala-cli Hello.scala
# Hello from Scala

You can also split your code into multiple files:

Messages.scala
object Messages {
def hello = "Hello from Scala"
}
Hello.scala
object Hello {
def main(args: Array[String]): Unit =
println(Messages.hello)
}

and the run them with scala-cli:

scala-cli Hello.scala Messages.scala
# Hello from Scala
note

Scala CLI compiles only the provided inputs. For example, if we provide only one of the files above:

scala-cli Hello.scala

compilation will fail. scala-cli compiles only the files it’s given.

While this is very convenient for projects with just a few files, passing many files this way can be cumbersome and error-prone. For larger projects, directories can help.

Directories

scala-cli accepts whole directories as input.

This is convenient when you have many .scala files, and passing them all one-by-one on the command line isn't practical:

my-app/Messages.scala
object Messages {
def hello = "Hello from Scala"
}
my-app/Hello.scala
object Hello {
def main(args: Array[String]): Unit =
println(Messages.hello)
}

For this case, run all the source code files in my-app by supplying the directory name:

scala-cli my-app
# Hello from Scala

In our experience, scala-cli . is the most used command; it compiles and runs all sources in the current directory.

note

Scala CLI process all files within the specified directories and all of its subdirectories.

Scala CLI ignores all subdirectories that start with . like .scala or .vscode. Such directories needs to be explicitly provided as inputs.

URLs

warning

Running unverified code from the internet can be very handy for trusted sources, but it can also be really dangerous, since Scala CLI does not provide any sandboxing at this moment.

Make sure that you trust the code that you are about to run.

scala-cli accepts input via URLs pointing at .scala files. It downloads their content, and runs them:

scala-cli https://gist.github.com/alexarchambault/f972d941bc4a502d70267cfbbc4d6343/raw/2691c01984c9249936a625a42e29a822a357b0f6/Test.scala
# Hello from Scala GitHub Gist

GitHub Gist

scala-cli accepts input via Github Gist’s urls. It downloads the gist zip archive and runs it:

scala-cli https://gist.github.com/alexarchambault/7b4ec20c4033690dd750ffd601e540ec
# Hello

Piping

You can also pipe Scala code to scala-cli for execution:

echo 'println("Hello")' | scala-cli -
# Hello

Process substitution

Lastly, scala-cli also accepts input via shell process substitution:

scala-cli <(echo 'println("Hello")')
# Hello