CLI frameworks for Kotlin: creating powerful console applications
Kotlin is a modern language that is actively used not only for Android development but also for creating server and console applications. Developing CLI (Command Line Interface) tools in Kotlin can be significantly simplified with specialized frameworks. In this article, we will look at three of the most popular solutions: Clikt, Kotlinx-cli, and Aigrette, and analyze them with practical examples.
Why do you need a CLI framework?
Writing a command line argument parser manually is a tedious and error-prone task. CLI frameworks provide:
- Automatic parsing of arguments and options
- Help generation (
--help) - Input validation
- Support for subcommands
- Error handling with clear messages
Clikt — the most popular choice
Clikt is a powerful and flexible library that has become the de facto standard for CLI in Kotlin. It uses a declarative approach with annotations and provides a rich API.
Installation (via Gradle):
implementation("com.github.ajalt.clikt:clikt:4.2.1")Example of a simple application:
import com.github.ajalt.clikt.core.CliktCommandimport com.github.ajalt.clikt.parameters.arguments.argumentimport com.github.ajalt.clikt.parameters.options.optionimport com.github.ajalt.clikt.parameters.types.int
class Greet : CliktCommand() { val name by argument() val count by option("--count", "-c", help = "Number of repetitions").int().default(1)
override fun run() { repeat(count) { echo("Hello, $name!") } }}
fun main(args: Array<String>) = Greet().main(args)Run:
./app --count 3 Ivan# Output:# Hello, Ivan!# Hello, Ivan!# Hello, Ivan!Clikt supports nested commands, autocomplete, console colors, and strict typing. For complex projects (e.g., DevOps tools, API utilities), this is the best choice.
Kotlinx-cli — a lightweight solution from JetBrains
Kotlinx-cli is an official library from the creators of Kotlin. It is less feature-rich than Clikt but is ideal for simple utilities and small projects.
Installation:
implementation("org.jetbrains.kotlinx:kotlinx-cli:0.3.6")Example:
import kotlinx.cli.*
fun main(args: Array<String>) { val parser = ArgParser("file-util") val input by parser.argument(ArgType.String, description = "Input file") val output by parser.option(ArgType.String, shortName = "o", description = "Output file").default("out.txt") val verbose by parser.option(ArgType.Boolean, shortName = "v", description = "Verbose output").default(false)
parser.parse(args)
println("Reading from: $input") println("Writing to: $output") if (verbose) println("Verbose mode enabled")}Kotlinx-cli requires no additional dependencies and is great for rapid prototyping. However, it does not support nested commands or complex validation.
Aigrette — a functional approach
Aigrette is a lesser-known but interesting library that uses a functional style. It is based on the concept of "parser combinators".
Installation:
implementation("io.github.petertrr:aigrette:0.3.0")Example:
import io.github.petertrr.aigrette.*
data class Config(val name: String, val age: Int, val flag: Boo Also in library
Authorization and Authentication in PHP: A Complete Guide with Examples
JWT tokens in Rust: jsonwebtoken library and authentication
Authorization and Authentication in Kotlin: JWT, Spring Security and Ktor
Task Queues in TypeScript: Library Overview and Implementation
Sending email in Kotlin: libraries, examples, and SMTP setup