CLI frameworks for Java: overview and comparison of the best tools

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

CLI frameworks for Java: building powerful console applications



Developing complex console applications in Java requires not only logic but also a convenient command-line interface (CLI). Parsing arguments, handling options, displaying help — manually implementing these tasks is time-consuming and error-prone. Fortunately, there are mature CLI frameworks that automate this process. In this article, we will take a detailed look at three leading tools: Picocli, JCommander, and Spring Shell, with code examples and recommendations for choosing.



1. Picocli — modern and high-performance



Picocli (https://picocli.info/) is the most popular CLI framework for Java today. Its key advantage is a minimalist API based on annotations and support for Java as well as Kotlin, Groovy, and Scala. The library has no external dependencies and can generate autocompletion for Bash, Zsh, and Fish.



Key features of Picocli:

  • Annotations @Command, @Option, @Parameters
  • Automatic help generation (--help)
  • Nested commands (subcommands)
  • Support for value types (int, boolean, enum, LocalDate)
  • Custom converters and validators


Example of a simple application with Picocli:

import picocli.CommandLine;import picocli.CommandLine.Command;import picocli.CommandLine.Option;import picocli.CommandLine.Parameters;

@Command(name = "greet", description = "Greets the user")public class GreetApp implements Runnable {

@Option(names = {"-n", "--name"}, defaultValue = "world", description = "Name to greet") private String name;

@Option(names = {"-c", "--count"}, defaultValue = "1", description = "Number of repetitions") private int count;

@Override public void run() { for (int i = 0; i < count; i++) { System.out.println("Hello, " + name + "!"); } }

public static void main(String[] args) { int exitCode = new CommandLine(new GreetApp()).execute(args); System.exit(exitCode); }}


Execution:

java GreetApp --name="Java developer" --count=3


Output:

Hello, Java developer!Hello, Java developer!Hello, Java developer!


2. JCommander — a proven classic



JCommander (https://jcommander.org/) is a mature library with a rich history (since 2011). It also uses annotations but offers a more flexible architecture for complex scenarios. JCommander is especially convenient for projects that require strict control over parsing and error handling.



Key features of JCommander:

  • Annotations @Parameter with attributes names, required, description
  • Support for multi-level commands via Commands
  • Built-in parameter validator
  • Ability to use arbitrary types through converters


Example with JCommander:

import com.beust.jcommander.JCommander;import com.beust.jcommander.Parameter;import com.beust.jcommander.Parameters;

@Parameters(commandDescription = "Calculator")public class Calculator {

@Parameter(names = {"--a"}, description = "First number", required = true) private int a;

@Parameter(names = {"--b"}, description = "Second number", required = true) private int b;

@Parameter(names = {"--op"}, description = "Operation: add, sub, mul, div") private String operation = "add";

public void run() { int result; switch (operation) { case "add": result = a + b; break; case "sub": result = a - b; break; case "mul

Recommendations