What it is
kotlinx-cli is JetBrains' Multiplatform command-line argument parser, with typed options, subcommands and generated help.
Create an ArgParser, declare options and arguments as delegated properties, and call parse. Types are enforced and help text is generated.
Installation
implementation("org.jetbrains.kotlinx:kotlinx-cli:0.3.6")Getting started
The smallest useful thing you can do with it, and what each part means.
kotlin
fun main(args: Array<String>) {
val parser = ArgParser("library")
val input by parser.argument(ArgType.String, description = "Input file")
val output by parser.option(
ArgType.String, shortName = "o", description = "Output file"
).default("out.json")
val verbose by parser.option(
ArgType.Boolean, shortName = "v", description = "Verbose output"
).default(false)
val format by parser.option(
ArgType.Choice<Format>(), description = "Output format"
).default(Format.JSON)
parser.parse(args) // exits with help on error
if (verbose) println("reading $input")
convert(input, output, format)
}Advanced usage
Where the library earns its place over a simpler alternative.
kotlin
class Add : Subcommand("add", "Add a book") {
val title by argument(ArgType.String, description = "Book title")
val year by option(ArgType.Int, description = "Year").default(0)
override fun execute() {
store.add(title, year)
}
}
class Remove : Subcommand("remove", "Remove a book") {
val id by argument(ArgType.Int)
override fun execute() = store.remove(id)
}
val parser = ArgParser("library")
parser.subcommands(Add(), Remove())
parser.parse(args) // dispatches to execute() on the matched subcommandErrors and fixes
The failures you are most likely to hit, and what actually resolves them.
- Value is not provided for the argument
- A required positional argument was omitted. Give it a default, or make it optional.
- A feature is missing compared to other parsers
- kotlinx-cli is deliberately minimal. Use Clikt if you need completions, prompts or config-file layering.
Best practices
- Use it for Kotlin/Native and Multiplatform tools; prefer Clikt on JVM-only projects.
- Give every option a description — it becomes the generated help text.
- Use ArgType.Choice with an enum rather than validating strings by hand.
- Keep execute() thin and delegate to real functions so the logic stays testable.
Background
Why it exists, and what it was reacting to.
It exists so Kotlin/Native command-line tools can parse arguments without depending on a JVM library. On JVM-only projects, Clikt is generally the richer choice.
