Installing Kotlin

Before you can write a single line of Kotlin, you need a working toolchain: something that turns your .kt source files into a program you can actually run. That toolchain is the Kotlin compiler, kotlinc, plus a Java Virtual Machine to run the result on. This lesson walks through every practical way to get Kotlin installed — standalone command-line tools, the bundled compiler inside IntelliJ IDEA, and build-tool-managed installs — and shows you how to verify the install by compiling and running real programs.

Overview / How Kotlin Installation Works

Kotlin is a statically typed language created by JetBrains that targets the Java Virtual Machine (JVM) by default. When you install “Kotlin,” what you are really installing is the Kotlin compiler — the kotlinc command — which reads your .kt source, performs full type checking (including Kotlin’s compile-time null-safety analysis), and emits standard JVM bytecode: the same .class file format that Java’s javac produces. Because the output is ordinary JVM bytecode, there is no separate “Kotlin runtime machine” — your compiled program executes on any standard Java Runtime Environment (JRE). This means a working JDK is not optional; it is a prerequisite. Modern Kotlin releases (2.x) are built and tested against JDK 17 and newer, so installing a recent JDK is the first real step, even before installing Kotlin itself.

There are three common paths to a working Kotlin setup, and most developers eventually use more than one:

  • IntelliJ IDEA (Community Edition, free) — the officially recommended path for most learners. IntelliJ bundles its own copy of the Kotlin plugin and compiler, so creating a new Kotlin project, running it, and debugging it all work out of the box with no terminal commands required.
  • Standalone command-line tools — installed with a package or version manager: SDKMAN on macOS/Linux, Homebrew on macOS, or Chocolatey/Scoop on Windows. These put the kotlinc and kotlin executables directly on your system PATH, which is the path most tutorials (including this one) assume when they show terminal commands.
  • A build tool like Gradle — for real projects, you usually don’t install Kotlin globally at all. Instead, you declare a Kotlin version in build.gradle.kts, and Gradle downloads and manages that exact compiler version per project, so different projects can each pin their own Kotlin release without conflicting.

A typical SDKMAN-based install on macOS or Linux looks like this:

$ curl -s "https://get.sdkman.io" | bash
$ source "$HOME/.sdkman/bin/sdkman-init.sh"
$ sdk install kotlin
$ kotlinc -version

It’s also worth knowing about two related tools you’ll see mentioned: the Kotlin Playground (an in-browser compiler at play.kotlinlang.org) requires no installation at all and is great for a first look or for sharing a snippet, but it is not a substitute for a real project setup. And the kotlin command (distinct from kotlinc) can both compile and run a single .kt file in one step, which is convenient for quick experiments.

Syntax

“Syntax” for an installation lesson means the shape of the commands you’ll run, not Kotlin language syntax. The table below is the reference you’ll come back to.

Command What it does
kotlinc -version Prints the installed compiler version — the standard way to confirm the install worked.
kotlinc Hello.kt Compiles the file into .class files in the current directory. Does not run the program.
kotlinc Hello.kt -include-runtime -d app.jar Compiles and bundles the Kotlin standard library into a single runnable .jar.
kotlin Hello.kt Compiles and immediately runs a single Kotlin file — good for quick scripts and experiments.
java -jar app.jar Runs a previously compiled, self-contained jar on the JVM.
java -version Confirms a JDK is installed and visible on PATH, which kotlinc itself depends on.

Every runnable Kotlin file needs an entry point: a top-level fun main() (no wrapping class required — this is a deliberate improvement over Java, where public static void main must live inside a class). The compiler generates a hidden class behind the scenes (for a file named Hello.kt, it’s called HelloKt) that holds your top-level function as a real JVM main method.

Examples

Example 1: Hello, World! from the command line

Save the following as Hello.kt. It uses a top-level fun main() with no parameters — the modern, idiomatic form — and a string template ("..." with an embedded variable) rather than string concatenation.

fun main() {
    val greeting = "Hello, Kotlin!"
    println(greeting)
}

Compile it into a runnable jar and execute it:

$ kotlinc Hello.kt -include-runtime -d hello.jar
$ java -jar hello.jar

Output:

Hello, Kotlin!

The -include-runtime flag matters: without it, hello.jar would contain only your compiled class, and running it would fail with a NoClassDefFoundError because the Kotlin standard library classes (used even by println) wouldn’t be on the classpath.

Example 2: Verifying the install with command-line arguments

This program is a slightly more realistic check — it uses the classic fun main(args: Array<String>) form, which is still valid Kotlin and is how you access arguments passed on the command line. args is a non-null Array<String>: if no arguments are passed, it is an empty array, never null.

fun main(args: Array<String>) {
    println("Number of arguments: ${args.size}")
    if (args.isEmpty()) {
        println("No arguments passed.")
    } else {
        for (arg in args) {
            println("Arg: $arg")
        }
    }
}

Run it with the kotlin command, which compiles and executes in one step — handy for quick checks like this one:

$ kotlin Args.kt Alice Bob Carol

Output:

Number of arguments: 3
Arg: Alice
Arg: Bob
Arg: Carol

If you run kotlin Args.kt with no arguments at all, args.size is 0 and the else branch never executes — you’d instead see the “No arguments passed.” line, which is exactly what a working install with zero setup mistakes should print.

Example 3: A quick sanity check with the Kotlin REPL

Every Kotlin install also includes a REPL (Read-Eval-Print Loop), started by running kotlinc with no file argument. It’s the fastest way to confirm the compiler works without creating any files:

Welcome to Kotlin version 2.0.20 (JRE 21.0.3+9)
Type :help for help, :quit for quit

>>> val x = 5
>>> val y = 10
>>> println(x + y)
15
>>> :quit

Each line you type at the >>> prompt is compiled and executed immediately, and the REPL remembers previously declared values (x and y) across lines — useful for exploring standard library functions interactively, though it’s not a substitute for a real project when you’re building something more than a one-off experiment.

How It Works Step by Step

Walking through kotlinc Hello.kt -include-runtime -d hello.jar followed by java -jar hello.jar:

  1. kotlinc parses Hello.kt into an abstract syntax tree and resolves every reference (types, function calls, imports).
  2. The compiler runs full type checking, including null-safety analysis — this is the stage that would reject, for example, assigning a nullable expression to a non-nullable type.
  3. Assuming everything type-checks, the compiler emits JVM bytecode. Your top-level fun main() becomes a real public static void main method on a generated class named HelloKt.
  4. Because -include-runtime was passed, kotlinc also copies the required Kotlin standard library classes into the output and writes a META-INF/MANIFEST.MF file pointing Main-Class at HelloKt, then packages everything into hello.jar.
  5. When you run java -jar hello.jar, the JVM reads the manifest, loads HelloKt, and invokes its main method — exactly like it would for a compiled Java program.
  6. println writes to standard output, which your terminal displays.

The single-step kotlin Hello.kt command (used in Example 2) does the same compile-then-load sequence internally, but skips writing a permanent jar — it compiles to a temporary location, runs it, and discards the artifacts afterward. That’s why it’s convenient for scripts but not what you’d use to ship a distributable program.

Common Mistakes

Mistake 1: Expecting kotlinc alone to run your program

kotlinc is a compiler, not a runner. By itself it silently produces .class files and prints nothing:

$ kotlinc Hello.kt
$ 
(no output — kotlinc only compiled HelloKt.class; it never executed anything)

New Kotlin users sometimes assume the program ran because no error appeared. It didn’t run — it only compiled. To actually execute it, either run the generated class with kotlin -classpath . HelloKt, build a runnable jar with -include-runtime -d app.jar and use java -jar app.jar, or skip the manual compile step entirely and use kotlin Hello.kt to compile and run in one command, as shown in Example 2.

Mistake 2: Installing via IntelliJ IDEA only, then expecting a terminal to find kotlinc

IntelliJ IDEA bundles its own copy of the Kotlin compiler for use inside the IDE, but that bundled copy is not automatically added to your system PATH. Opening a plain terminal (outside the IDE) after only installing IntelliJ often produces this:

$ kotlinc -version
bash: kotlinc: command not found

This isn’t a broken install — IntelliJ projects still build and run fine inside the IDE. It just means the standalone kotlinc/kotlin commands aren’t available outside it. If you want a terminal-usable compiler too, install it separately with SDKMAN, Homebrew, or Chocolatey:

$ sdk install kotlin
$ kotlinc -version
Kotlin version 2.0.20-release-...

Mistake 3: Wrapping main inside a class out of Java habit

Developers coming from Java sometimes write:

class Main {
    fun main() {
        println("Hello from inside a class")
    }
}

This compiles without error, but it does not create a usable JVM entry point — main here is just an ordinary member function that has to be called on an instance of Main. Running it with kotlin or java -jar fails because no top-level main function was generated. The fix is simply to drop the class wrapper and declare fun main() at the top level of the file, exactly as in Example 1 — one of the places Kotlin is a genuine simplification over Java, which requires the class.

Best Practices

  • Install a JDK first (17 or newer) and confirm it with java -version before installing Kotlin — kotlinc depends on it.
  • Use SDKMAN (macOS/Linux) or Chocolatey/Scoop (Windows) if you want multiple Kotlin versions available and easily switchable on one machine.
  • For your very first project, install IntelliJ IDEA Community Edition — it removes almost all setup friction and is what most Kotlin tutorials assume.
  • Always verify an install with kotlinc -version immediately after installing, rather than assuming success.
  • For anything beyond a single file, use Gradle with the Kotlin DSL (build.gradle.kts) and let it pin the Kotlin version per project — this avoids “works on my machine” version drift between contributors.
  • Use the single-step kotlin file.kt command for quick, throwaway experiments; use a full compile-to-jar workflow (or a build tool) for anything you intend to distribute or run repeatedly.
  • Don’t mix a globally installed compiler version with a Gradle-pinned one in the same project without understanding which one actually builds your code — Gradle’s declared version wins for that project regardless of what kotlinc -version reports globally.

Practice Exercises

  • Install Kotlin on your machine using SDKMAN, Homebrew, or by installing IntelliJ IDEA Community Edition. Run kotlinc -version (or check the Kotlin plugin version in IntelliJ’s settings) and note the exact version string you get.
  • Write your own Hello.kt that prints a greeting containing your name using a string template (not concatenation), then compile it with kotlinc -include-runtime -d and run the resulting jar with java -jar.
  • Take the Args.kt program from Example 2 and modify it to also print the arguments in reverse order using the standard library’s reversed() function on the list. Predict the output for kotlin Args.kt Alice Bob Carol before you run it, then check yourself.

Summary

  • Installing “Kotlin” means installing the kotlinc compiler (and the kotlin runner), which requires a working JDK (17+ recommended) because Kotlin compiles to standard JVM bytecode.
  • The three main installation paths are: IntelliJ IDEA (bundled, easiest for beginners), standalone tools via SDKMAN/Homebrew/Chocolatey (adds kotlinc/kotlin to your PATH), and Gradle-managed installs (per-project, no global install needed).
  • kotlinc only compiles; it never runs your program by itself. Use java -jar on a built jar, or the single-step kotlin file.kt command.
  • Every runnable Kotlin file needs a top-level fun main() — no wrapping class required, unlike Java.
  • IntelliJ’s bundled compiler and a standalone terminal kotlinc are separate things; having one doesn’t guarantee the other is on PATH.
  • Always confirm an install with kotlinc -version and java -version rather than assuming it worked.