Why Kotlin is the Ideal Language for CLI Utilities?
\n\nWhen it comes to creating console tools, many developers habitually reach for Python or Bash. But if you are already familiar with Kotlin (and on our website pythonlib.ru we believe that a good developer masters several languages), then you know how concise and expressive this language is. Creating CLI utilities in Kotlin is not just a trend, but a real way to get fast, type-safe, and cross-platform tools.
\n\nImagine: you write a Kotlin console application that compiles into a JAR or a native binary via GraalVM or Kotlin/Native. It runs everywhere — from a Linux server to a colleague's Windows machine. At the same time, the code is 2-3 times shorter than in Java, and much safer than in Python. Sounds tempting? Let's dive in.
\n\nWhat Do You Need to Start?
\n\nTo create a Kotlin CLI you will need a minimum:
\n- \n
- Installed JDK 11+ (I recommend 17 or 21) \n
- IntelliJ IDEA (Community edition is enough) or any text editor \n
- Basic knowledge of Kotlin (functions, classes, collections) \n
- Gradle or Maven for building \n
If you haven't worked with Kotlin in the console before — no problem. We will go from an empty file to a full-fledged utility that can be published and used in CI/CD pipelines.
\n\nStep 1: Setting Up the Project for a CLI Utility
\n\nLet's create a simple Gradle project. Here is the minimal build.gradle.kts:
plugins {\n kotlin("jvm") version "1.9.22"\n application\n}\n\napplication {\n mainClass.set("com.pythonlib.cli.MainKt")\n}\n\nrepositories {\n mavenCentral()\n}\n\ndependencies {\n implementation("com.github.ajalt.clikt:clikt:4.2.2")\n implementation("org.jetbrains.kotlinx:kotlinx-cli:0.3.6")\n}\n\nNotice two key libraries: Clikt and Kotlinx CLI. The first is the most popular library for creating CLI utilities in Kotlin. The second is the official solution from JetBrains. In this article, we will use Clikt, as it provides more flexibility and looks nicer.
\n\nStep 2: Writing the First Command
\n\nLet's create the file src/main/kotlin/com/pythonlib/cli/Main.kt:
package com.pythonlib.cli\n\nimport com.github.ajalt.clikt.core.CliktCommand\nimport com.github.ajalt.clikt.parameters.arguments.argument\nimport com.github.ajalt.clikt.parameters.options.option\nimport com.github.ajalt.clikt.parameters.options.flag\n\nclass GreetCommand : CliktCommand(\n name = "greet",\n help = "Greets the user"\n) {\n private val name: String by argument(\n help = "User name"\n )\n\n private val uppercase: Boolean by option(\n "--uppercase", "-u",\n help = "Print the name in uppercase"\n ).flag()\n\n override fun run() {\n val greeting = "Hello, $name!"\n if (uppercase) {\n echo(greeting.uppercase())\n } else {\n echo(greeting)\n }\n }\n}\n\nfun main(args: Array<String>) {\n GreetCommand().main(args)\n}\n\nThis is a simple Kotlin CLI utility that takes a name and an optional flag. Let's run it:
\n\n./gradlew run --args="Alexey --uppercase"\n# Output: HELLO, ALEXEY!\n\nJust 30 lines of code — and we have a working console tool. Clikt automatically generates help, handles errors, and supports autocomplete for bash/zsh.
\n\nStep 3: Multi-level Commands (like in Git)
\n\nReal Kotlin console applications rarely consist of a single command. Let's create a utility for working with files that supports subcommands:
\n\nimport com.github.ajalt.clikt.core.subcommands\n\nclass FileTool : CliktCommand(\n name