Typelevel Toolkit

by Rishad Sewnarain on Apr 03, 2023


Getting started in the wondrous world of functional programming using Typelevel libraries can be daunting. Before you can even write your first pure “Hello, World!” you’ll need to install a Java runtime, editor tooling and build tools. Then you’ll need to setup some project using sbt or mill. As an added consequence, after all the setup, the idea of using these battle-tested libraries for small scripts will seem like a chore. This is where Typelevel Toolkit comes in. It provides an easy start for beginning and experienced developers with Scala and functional programming.

scala-cli to the rescue

scala-cli is a command-line interface to quickly develop and experiment with Scala, it’s even on track to becoming the new scala command. The interface has a lot of advantages, but one of the most important ones is that it makes learning, developing and building Scala scripts and small applications friction-less and easy to use.

You can get scala-cli by following the installation instructions described here: https://scala-cli.virtuslab.org/docs/overview#installation. The great part here is that once you have scala-cli installed, it will take care of the rest: Java runtimes, editor tooling, compilation targets(including a native target!) and you can even use dependencies in your scripts!

An example of setting up your script

First off, let’s create a new directory that will contain our script(s).

mkdir myscript && cd myscript

Now we can use scala-cli to create all the files necessary for editor tooling to work:

scala-cli setup-ide .

Finally, let’s create a Scala file and try to compile it.

touch Main.scala
scala-cli compile --watch Main.scala

The last command also includes a --watch flag, so we can hack on our script and scala-cli will try to compile the file on every save. This creates a very nice feedback loop!

Putting the fun in functional

Typelevel Toolkit uses scala-cli and Typelevel libraries to provide a runway for your next Scala script or command-line interface. With a single line, Typelevel Toolkit gives you:

  • Cats Effect a production proven pure asynchronous runtime.
  • fs2 an amazing streaming I/O library.
  • http4s-ember-client for a full-fledged HTTP client.
  • circe for dealing with JSON.
  • MUnit an unit testing library and an integration to easily unit test pure functional programs.
  • fs2-data-csv for handling CSV files.
  • decline a composable commandline parser and it’s integration with Cats Effect.

Typelevel Toolkit shines with scala-cli, but it can also be used by sbt or mill if that is preferred. More concretely this means your next ad-hoc script won’t be Bash or Python spaghetti, but Scala code that can be a joy to hack on as time goes on, without the boilerplate.

You can use the toolkit by using a scala-cli directive

//> using dep "org.typelevel::toolkit::0.0.4"

This will pull in the typelevel/toolkit dependency and then you’re just an import away from your first pure functional “Hello, World!”:

import cats.effect.*

object Hello extends IOApp.Simple {
  def run = IO.println("Hello, World!")

You can compile and run this program by using a single command: scala-cli run Main.scala.

A “Hello, World!” is only the start, the goal here is to make functional programming friendly and practical. As such, Typelevel toolkit comes with examples that introduces beginners on how one can use the included libraries to achieve common tasks.

For the full list of libraries included in Typelevel Toolkit, please see the overview: https://typelevel.org/toolkit/#overview. If you feel like anything is missing, join the discussion.

We can have nice things

Typelevel libraries are production-proven, well tested, build upon rock solid semantics, and almost all have Scala 3 support. However their entry-point is higher than your usual scripting language. Pure functional programming has a reputation of being hard to learn, and Typelevel Toolkit is a way to play in that world, without learning an entire ecosystem first.

The libraries in the toolkit compliment each other and target common usecases, thus providing a coherent mini-ecosystem, that scales extremely well, thanks to Cats Effect. With support for other runtimes besides the JVM. This means that your scripts can run in a JavaScript environment, thanks to scala-js. Or you can use scala-native to get a native binary, just like Rust and Go!

scala-cli again, makes things easy for us by having simple commands to compile to a certain target:

# To compile to JavaScript
scala-cli Main.scala --js  

# To target native
scala-cli Main.scala --native

If you just want to explore Typelevel Toolkit, you can quickly open a REPL using the following command:

scala-cli repl --dep "org.typelevel::toolkit::0.0.4"

With scala-cli, there a few other cool things you get here:


scala-cli is great. It’s easy to get started with and great to use. Typelevel Toolkit leverages its versatility and provides a “pure functional standard library” in a single directive. This will enable you to create and develop scripts fast with high refactorability, an awesome developer experience and lots of functions that compose well! All those benefits while remaining beginner-friendly.