ki: The Next Interactive Shell for Kotlin

There are several options to run Kotlin interactively: kotlinc and Kotlin REPL (read-evaluate-print loop) in IntelliJ IDEA.

Neither is ideal. kotlinc does not have autocomplete or syntax highlighting. Kotlin REPL is very powerful, but it forces you to open IntelliJ IDEA, which is not always convenient.

Allow me to introduce you to ki, a Kotlin Interactive Shell, and describe its benefits below.

And its main features are:

Download ki


I like doing quick experiments with collections to find out what they have, what they do, and how I can obtain the desired result. The Kotlin collection API is huge, and it’s not humanly possible to remember everything it contains. Before ki, you had to go through the documentation a lot while working with kotlinc. This is a thing of the past with ki, as there is autocompletion to help! Here’s a quick example of how easy it is to write code in ki with the help of autocompletion.

One more thing to notice is that ki highlights the code, so it will be easier for me to read the code I wrote several inputs ago.

The nice thing we’ve kept from the original REPL in kotlinc is: every intermediate result is being written into variables named res0, res1, and so on. Each command is stored independently, which ensures I’ll be able to find any previous commands and reuse them.

Loading external dependencies

However, sometimes my experiments are a bit more complex than testing a random snippet. I may need to use a library, or write a throw-away one-liner using a 3rd-party library. For example, I like to use the Fuel HTTP client for HTTP interaction because it has an intuitive API.

ki has the :dependsOn construct for this particular scenario. It allows me to add a library from Maven Central to my classpath.

To illustrate this, let’s try to determine which HTTP headers the site sets when we’re visiting it.

No cookies – I love it already! But what is this mysterious component2 I used? Let’s find out.

Type inference

If I did not remember what component2 was, I could use the built-in :t command. It shows us that component2 is of type Response and the response method returns ResponseResultOf<ByteArray>, which is an alias of Triple<Request, Response, Result<ByteArray, FuelError>>.

Paste mode

Every now and then, I may want to insert a whole code snippet into my REPL, say, from Stack Overflow. How can I do that? I just need to type the :paste command to enter paste mode, like so:

Notice that the ki syntax highlights pasted elements, too. If I want to define a function myself, I can do it without paste mode. Syntax highlighting works the same for pasted code and code written right in the command-line.

Scripting support

What if I don’t want to import and add all the dependencies I need every time I launch ki? I can write a Kotlin script and load it into the shell! In the examples we’ve seen so far, almost everything can be expressed as a script:

I can run the :l command, and both my imports and sendGet function are accessible.

Take a look at how I’m invoking the :ls command to find which functions were defined by the script I’ve just loaded. In this case, it’s only the sendGet function, but obviously, there may be much more content: functions, classes, variables, and so on.

Please note that ki does not support the execution of commands, which means we should replace the :dependsOn command with an @file:DependsOn annotation, which is explicitly created for scripting in Kotlin.


Built with extensibility in mind, ki exposes the Plugin class, which lets developers extend the functionality of the shell. Like :l and :ls, all the commands mentioned above are implemented as plugins. The plugin class is self-descriptive and straightforward. Good examples of implemented plugins include the Paste Plugin and the Help Plugin.

One plugin that does not come included with the distribution is the Kotlin API for the Apache Spark plugin, just because there are not a lot of users for it.

ki for Apache Spark

We’ve created a separate shell for Kotlin API for Apache Spark Users that bundles ki. There are two versions of the shell: one for Apache Spark 2.4 and another for Apache Spark 3. They both work with your local installation of Apache Spark and don’t require any additional dependencies.

Upon startup, the shell initializes Apache Spark, and on first execution, it creates a local Spark context. Starting with the second execution, queries work much faster because they reuse the existing context that’s already started.

There is a spark variable implicitly defined to work with Spark and to call the Kotlin API’s specific methods, like toDS(). You can see an example of ki for Apache Spark working below.

Everything else works like it does in regular ki.
Give it a try!
If you like what you’ve just seen, please try it for yourself!
Download ki
Download ki for Apache Spark

Let us know what you think in the comments below or on Twitter.

image description