CLI tool
Kotlin/kotlin-interactive-shell avatar
Kotlin/kotlin-interactive-shell

kotlin-interactive-shell: a general purpose Kotlin REPL on the JVM

Kotlin Language Interactive Shell

615 stars42 forksJavaApache-2.0

At a glance

What is it?
ki is an extensible Kotlin REPL that adds syntax highlighting, type inference, runtime dependency download and symbol listing, and it grew out of the Spark shell, which explains both what it does well and the fact that its last tagged release is from 2022.
Who is it for?
ki is the right tool for a Kotlin developer who wants to try an API, check a type or pull a library into a scratch session without setting up a Gradle project, and it is the natural choice for people who used the Spark shell and want the same interaction with plain Kotlin.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

From the Spark shell to a general Kotlin REPL

The name of the artifact is ki-shell, and the history section of the README explains why. The project is the former Sparklin shell, migrated to the new Kotlin scripting and REPL infrastructure and converted into a generic Kotlin Language Interactive Shell. The Apache Spark adaptation of the same code lives in a separate repository, and the previous version of the Sparklin is still reachable in the sparklin branch.

That lineage explains the design. A REPL that grew up inside a distributed compute framework has to load libraries on demand, because a Spark session is expected to work with whatever jars a job needs, and it has to answer questions about types quickly, because the shell is used to explore a codebase rather than to run a program. Generalising it to plain Kotlin means keeping those capabilities and dropping the Spark specific parts.

For a reader deciding whether to use it, the practical question is what a general Kotlin REPL is for. It is the scratchpad: try a function, check what a generic type infers to, pull in a library by its Maven coordinates and call into it, all without writing a build file. The project is published on Maven Central as org.jetbrains.kotlinx:ki-shell and carries the JetBrains team project badge, so it sits in the same organisation as the language itself.

Four capabilities, and the one that changes how you work

The published feature list is short, and each entry solves a specific annoyance.

Syntax highlight is the first, which matters more in a REPL than it sounds, because a REPL is a place where you paste code fragments without a file to hold them. The type inference command is the second, and it is the one that makes this more than a Kotlin console: asking the shell what a type inferred to gives the answer that a compiler error would otherwise give you, but immediately and without a build step.

The third is downloading dependencies in runtime using Maven coordinates. This is the capability that changes how you work. Instead of adding a dependency to a build file, waiting for a resolution, and re-running, you can add a library inside a live session and start calling it. The fourth is listing declared symbols, which turns the shell into something you can interrogate rather than only write into.

Those four are the difference between an interactive console and a usable development tool. A plain Kotlin REPL without runtime dependency resolution is fine for testing your own functions and awkward for everything else, because any library that is not already on the classpath is out of reach. The rest of this article is mostly about how the project is distributed and how much of it still gets maintained, because those two things decide whether the capability is reachable in practice.

Six ways to install ki, and the one that gets you a current build

Six installation routes are documented, and they differ in an important way, because not all of them give you the same version.

The manual route is to download an archive from Maven Central or from the Releases page, unpack it somewhere, and launch the script for your platform. On Linux and macOS the command is bin/ki.sh, and on Windows it is bin\ki.bat. The other five routes hand the job to a package manager.

bash
sdk install ki
brew install ki

SDKMAN! and Homebrew both install a command called ki, and you can launch the shell with either ki or ki.sh afterwards. MacPorts uses the package name ki-shell.

bash
sudo port install ki-shell

On Arch Linux the AUR package is ki-shell-bin, and after installation you run the shell through ki. Nix is supported through nixpkgs, where the package is added to your environment or shell.

bash
nix-shell -p kotlin-interactive-shell

After that you launch with ki, exactly as the SDKMAN and Homebrew routes instruct.

The important detail is that a distribution package pins a version, and the versions in the distribution channels are not the same thing as the versions in the Releases page. The project states plainly that it aims to update weekly and that the Releases page will not carry the most stable build, since the newest version is published automatically through the build pipeline. If you want the current code rather than a packaged build from that year, the manual route is the one that tracks it.

Building from source with a pinned Kotlin version

The build is a standard Maven build, and the repository ships the wrapper, so a checkout is enough to compile it.

bash
git clone https://github.com/Kotlin/kotlin-interactive-shell
cd kotlin-interactive-shell
mvn -DskipTests package

The top level of the tree confirms the Maven layout, with a pom.xml, a mvnw and mvnw.cmd wrapper, an .mvn directory, a src directory, a ki-shell directory, a bin directory, a conf directory, a jreleaser.toml file and a set_default_release.sh script. The jreleaser configuration is what drives the automated publishing of new builds, and the set_default_release.sh script is the manual counterpart used to move the default release tag.

The more interesting flag is the Kotlin version override.

bash
mvn -Dkotlin.version=1.4.10 -DskipTests package

This is described as useful when you want to build the project with a specific version of Kotlin. It exists because the shell compiles against the Kotlin compiler internals, and those APIs change between language versions. A user building against a Kotlin version other than the default is not doing something exotic, they are doing something the project explicitly supports.

Once built, the launcher scripts are the same ones the manual install uses, so a source build and a downloaded archive behave identically once the classpath is in place.

Private Maven repositories through the :repository command

Runtime dependency download raises an obvious problem for anyone inside a company network, and the project has a command for it.

bash
:repository https://myrepo.org username=user password=pwd
:repository https:myrepo.org ./path/to/file

The first form takes a URL with a username and a password, and the second form points at a file on disk, which is described as a properties file that should contain a username and a password entry. The examples show both an equals syntax and a colon separated syntax for the credentials on the URL.

The second form is the interesting one, because it avoids putting a password on a command line, which would end up in shell history and in any process listing. Pointing at a local properties file keeps the credential in a file you can control the permissions of.

This is the part of the tool that matters most for a corporate user, since a REPL that cannot reach your internal repository cannot use your internal libraries, and an internal library is usually the reason you want a REPL in the first place. Note that the credential formats are documented, but nothing is said about how credentials are stored once supplied, which is a reasonable thing to check before typing a production password into it.

Where ki is the wrong tool

The weaknesses are about the surrounding engineering rather than the REPL itself.

The first is release staleness. The most recent tagged releases are v0.5.0, v0.5.1 and v0.5.2, published in June and July 2022, while the last push to the default branch was on 2026-10-09. The code is being worked on, but the packaged artifacts that most people install through a package manager are from 2022. A REPL is tied to the compiler version it links against, and a shell built against an old Kotlin will not necessarily behave well with a new one, which is exactly what the -Dkotlin.version build option is there to work around.

The second is that a REPL is interactive, which makes it a poor fit for anything that has to run unattended. There is no documented way to script a session for CI, and the documented way to end a session is to type :q or :quit, which is a description of an interactive tool rather than a batch one.

The third is scope. Only four capabilities and the installation and repository commands are documented. There is no documented configuration surface beyond the conf directory, no plugin API for adding shell commands, and no history or scripting features. For a tool whose pitch is extensibility, the visible extension point in the documentation is the :repository command.

Licence, packaging and what a maintainer signal looks like here

The licence is Apache 2.0, with a LICENSE file at the root of the repository. That is a permissive grant, so the code can be embedded in internal tooling and modified, with the notice preserved, and it comes with an express patent grant. This is not legal advice, but a permissive licence with a clear patent clause is straightforward for a company to accept.

The publishing story is the part that deserves attention. Releases are handled by jreleaser.toml and a set_default_release.sh script, and the newest version is published automatically through the build pipeline while the Releases page deliberately avoids carrying the most stable build. In effect, the project has a continuous delivery model for its own developers and a separate, slower channel for users.

That arrangement is a reasonable choice for a tool that has to track a fast moving compiler, and it has a cost for users. If you install from a package manager you get a 2022 build, and if you want current behaviour you have to build from source with a Kotlin version you choose. The repository carries the JetBrains team project badge and the Kotlin stable badge, so the project is treated as part of the Kotlin ecosystem rather than as a third party tool, and the recent commit activity is consistent with that.

The two concrete things to check before committing to it are the Kotlin version you will build against, and whether the artifact under org.jetbrains.kotlinx:ki-shell resolves for the platform you run.

Editorial conclusion

ki is the right tool for a Kotlin developer who wants to try an API, check a type or pull a library into a scratch session without setting up a Gradle project, and it is the natural choice for people who used the Spark shell and want the same interaction with plain Kotlin. It is the wrong tool for a team that needs a scripted, reproducible REPL in CI, and the wrong choice if you need a version that tracks current Kotlin releases, since the last tagged release is v0.5.2 from 2022-07-07 even though the repository is still being pushed to. Before adopting, check the mvn -Dkotlin.version build option against the Kotlin version you intend to use and confirm the artifact under org.jetbrains.kotlinx:ki-shell resolves for your target platform.

Frequently asked questions

What is ki in the Kotlin ecosystem?

ki is the Kotlin Language Interactive Shell, an extensible implementation of the Kotlin REPL that adds syntax highlighting, a type inference command, downloading dependencies in runtime using Maven coordinates, and listing of declared symbols. The artifact is published on Maven Central as org.jetbrains.kotlinx:ki-shell.

How do I install the Kotlin interactive shell?

Six routes are listed: downloading an archive and running bin/ki.sh on Linux and macOS or bin\ki.bat on Windows, SDKMAN! with sdk install ki, Homebrew with brew install ki, MacPorts with sudo port install ki-shell, the ki-shell-bin AUR package on Arch Linux, and nixpkgs with nix-shell -p kotlin-interactive-shell.

How do I use a private Maven repository with ki?

The :repository command accepts a URL with a username and a password, and it also accepts a path to a local properties file that holds the username and password entries. Both forms are documented under adding maven repositories that require auth.

How do I build ki from source with a specific Kotlin version?

Clone the repository and run mvn -DskipTests package, or add -Dkotlin.version=1.4.10 to build against that specific Kotlin version, as documented for building the project with a chosen Kotlin release. The repository includes the mvnw wrapper, and the shell is started with bin/ki.sh or bin\ki.bat.

What is the relationship between ki and the Spark shell?

The project is the former Sparklin shell, migrated to the new Kotlin scripting and REPL infrastructure and converted into a generic Kotlin Language Interactive Shell. The Apache Spark adaptation lives in a separate repository, and the previous version of the Sparklin is available in the sparklin branch.

Official sources

  1. Issues
  2. Kotlin/kotlin-interactive-shell on GitHub
  3. License: Apache-2.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/kotlin-kotlin-interactive-shell.svg)](https://hysenlabs.com/projects/kotlin-kotlin-interactive-shell)

Was this useful?