May 2020: The state of Kotlin Scripting

I am a huge Kotlin fan. I’m using Kotlin daily for Android development, sometimes a little bit of macOS and occasionally on the backend to power a small API. Lately, I started replacing my Bash and Python scripts with Kotlin and I’m loving Kotlin even more!

I won’t go into the many advantages of using the same language for everything and avoiding context changes or the great tooling that comes with a strongly typed language like Kotlin. If you ever had to read a perl script written by someone else, you’ll know what I mean. Instead, I’ll try to explain where Kotlin scripting is coming from, what’s possible today and what still remains to be done.

Mentmore Regent fountain pen by Athanasius

What is Kotlin Scripting?

Kotlin Scripting is:

  • A way to easily compile Kotlin source files…
  • … with a given context, i.e. a set of variables/methods accessible to the script.

Most of us are actually already using Kotlin Scripts in the form of build.gradle.kts files. These files know about the current Project, which is exposed as context.

Thinking forward, this could be used in a lot of different places like games scripting engines or maybe browser extensions one day.

For the time being, I’m mainly interested in replacing my Python or Bash scripts and there are 2 solutions for this:

Kscript

// hello.kts
#!/usr/bin/env kscript
println("my args are ${args.joinToString(",")}")

You can make hello.kts executable and run it:

$ chmod +x hello.kts$ ./hello.kts a few arguments
my args are a,few,arguments

Pretty neat right ?

Autocomplete in your Kotlin scripts

Kscript has a lot of features:

  • Scripts caching: Running the same script will be way faster the second time.
  • Maven dependencies: If you want to use OkHttp in your scripts, just drop @file:DependsOn("com.squareup.okhttp3:okhttp:4.7.2") and say goodbye to curl/wget.
  • IntelliJ support: Kscript generates an intelliJ project to edit your scripts with autocomplete.
  • Bootstrap header: To make you script install kscript automagically.
  • And a lot of other ones: See the kscript repo for the list.

And a few drawbacks:

  • It requires a local Kscript install on your machine. This is pretty easy to do thanks to SdkMan but still annoying when distributing scripts or trying to run them in your CI.
  • Dependency resolution doesn’t work with Java11. You will be stuck with Java8. Again, you can have multiple JDKs installed on your machine but it’s still annoying.

Kotlin-main-kts

You can now name a file *.main.kts and make it executable, just like with Kscript except the file will need to end with *.main.kts:

// hello.main.kts
#!/usr/bin/env kotlin
println("my args are ${args.joinToString(",")}")

Everything else works pretty much as you would expect, with arguments, autocomplete, etc.

Autocomplete your *.main.kts files directly in IntelliJ

Compared to Kscript, Kotlin-main-kts has less features but also less friction. It has the following advantages:

  • First party support.
  • Directly edit in intelliJ. No need for a wrapper Gradle project.
  • Only Kotlin is required, not need to install anything else.

And a few drawbacks:

  • No builtin bootstrap header and other nice helpers from Kscript.
  • Dependency resolution is limited.

That last one is a bit annoying. Snaphots are not resolved and dependency resolution will only take the first version encountered, even if another lib requires a higher one. Luckily, the team is working on it for Kotlin 1.4 so hopefully this will become even better soon.

Conclusion

Happy scripting!

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store