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
kotlincandkotlinexecutables directly on your systemPATH, 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:
kotlincparsesHello.ktinto an abstract syntax tree and resolves every reference (types, function calls, imports).- 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.
- Assuming everything type-checks, the compiler emits JVM bytecode. Your top-level
fun main()becomes a realpublic static void mainmethod on a generated class namedHelloKt. - Because
-include-runtimewas passed,kotlincalso copies the required Kotlin standard library classes into the output and writes aMETA-INF/MANIFEST.MFfile pointingMain-ClassatHelloKt, then packages everything intohello.jar. - When you run
java -jar hello.jar, the JVM reads the manifest, loadsHelloKt, and invokes itsmainmethod — exactly like it would for a compiled Java program. printlnwrites 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 -versionbefore installing Kotlin —kotlincdepends 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 -versionimmediately 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.ktcommand 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 -versionreports 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.ktthat prints a greeting containing your name using a string template (not concatenation), then compile it withkotlinc -include-runtime -dand run the resulting jar withjava -jar. - Take the
Args.ktprogram from Example 2 and modify it to also print the arguments in reverse order using the standard library’sreversed()function on the list. Predict the output forkotlin Args.kt Alice Bob Carolbefore you run it, then check yourself.
Summary
- Installing “Kotlin” means installing the
kotlinccompiler (and thekotlinrunner), 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/kotlinto yourPATH), and Gradle-managed installs (per-project, no global install needed). kotlinconly compiles; it never runs your program by itself. Usejava -jaron a built jar, or the single-stepkotlin file.ktcommand.- Every runnable Kotlin file needs a top-level
fun main()— no wrapping class required, unlike Java. - IntelliJ’s bundled compiler and a standalone terminal
kotlincare separate things; having one doesn’t guarantee the other is onPATH. - Always confirm an install with
kotlinc -versionandjava -versionrather than assuming it worked.
