# picocli: a command line framework you can paste into your project

> A Java CLI framework with usage help, autocompletion and nested subcommands, distributed as a single source file so your users never add it as a dependency. 5,425 stars, and a release that is more than a year older than the last commit.

**remkop/picocli** — Picocli is a modern framework for building powerful, user-friendly, GraalVM-enabled command line apps with ease. It supports colors, autocompletion, subcommands, and more.  In 1 source file so apps can include as source & avoid adding a dependency. Written in Java, usable from Groovy, Kotlin, Scala, etc. 

- Repository: https://github.com/remkop/picocli
- Website: https://picocli.info
- Stars: 5,433 · Forks: 491
- Language: Java
- License: Apache-2.0
- Published: 2026-10-08 · Updated: 2026-10-08 · Language: en
- Canonical page: https://hysenlabs.com/projects/remkop-picocli

## The distribution model is the unusual part

Almost everything else about picocli is a normal Java library. The one decision that shapes how you adopt it is that it can be delivered as a single source file.

The README states this directly: in a single file, so you can include it in source form, which lets users run picocli-based applications without requiring picocli as an external dependency. The repository has a picocli-codegen/ module, and that is the machinery. Instead of adding a jar to the classpath, you run a code generator over your annotated command classes and commit or ship the resulting single Java file.

For an application distributed as an executable jar this is a modest convenience. For a tool distributed as a script, or embedded in a larger distribution where dependency resolution is someone else's problem, it removes an entire class of friction. There is no version conflict to negotiate and no transitive dependency to audit, because there is nothing on the classpath but your own code.

The rest of the framework follows from an annotations API with a programmatic API alongside it. You annotate a class, picocli initializes it from the command line arguments and converts the input into strongly typed data, and the command itself can implement Runnable or Callable so that executing it takes a single line. The business logic can equally live in a method on a class marked with the command annotation, which is the shape most projects settle on.

The scale is substantial: 5,425 stars and 486 forks, with 175 open issues at the time of writing. That fork count is high for a library and is consistent with the source file model, where vendoring the generated file into your own tree is a normal thing to do.

## What the framework actually covers

The feature list is long, and rather than repeat it, it is more useful to group it by what problem it solves on a command line.

Options and parameters come first. Picocli distinguishes named options from positional parameters and makes both strongly typed. Multi-valued fields can declare an exact count or a range, and Map options support the property syntax that build tools made familiar:

```bash
-Dkey1=val1 -Dkey2=val2
```

Arity is expressed as a range rather than inferred, using the same notation throughout, for example `0..*` for any number of values or `1..2` for one or two. Being explicit about arity is what lets the generated usage help say something useful instead of repeating the option name.

Subcommands come next, git-style, including nested sub-subcommands, which is how you get a tool with a real command tree rather than a flat flag soup. Custom type converters cover the cases where a string is not the type you want, and password options read a value interactively rather than from the argument list, which is the difference between a password flag that works and one that leaks into shell history.

Completion and help generation are the parts users notice. Usage help and version help are generated, with ANSI colors and styles where the terminal supports them. Autocompletion shows available options and subcommands interactively, and when an option declares completion candidates or has an enum type, values are suggested too. Completion scripts can be generated for bash and zsh, and two modules in the repository, picocli-shell-jline2 and picocli-shell-jline3, provide JLine Completer implementations for building interactive shell applications.

A few features have no equivalent in most competitors. Negatable options produce a --no- form of a boolean. Quoted values let a single argument carry structured data. Argument groups express mutual exclusion, mutual dependency, help sections and repeating composite patterns. Parser tracing exists for troubleshooting, which is a small thing that saves hours when a command line is misbehaving. And @-files let an application accept argument files for command lines too long to type.

## Ahead-of-time compilation and framework integrations

Picocli-based applications can be compiled ahead of time to a GraalVM native image, which the README describes as producing extremely fast startup time and lower memory requirements, distributed as a single executable file. The annotation processor that ships with picocli automatically Graal-enables your jar during compilation.

That last sentence is the part that matters. Native image builds routinely fail on code that reflects over itself, and a command line parser is built on annotations and reflection. Shipping the configuration as part of compilation means you find out at build time rather than at first run in production.

Framework integration is broad enough that you should check whether your stack already has an answer before wiring picocli in by hand. Micronaut has built-in support for picocli. Quarkus has a Command Mode with Picocli extension for building CLI applications on Quarkus. The repository itself ships a picocli-spring-boot-starter module, and the README describes integration with dependency injection containers as straightforward rather than incidental.

The repository layout supports this breadth. Alongside the core src/ directory there are modules for code generation, examples, Groovy, the two JLine shell integrations, the Spring Boot starter, and four test modules split by Java generation: picocli-tests-java567, picocli-tests-java8, picocli-tests-java9plus, and picocli-tests-jpms-modules. That last one is worth noting, since module path testing is a separate concern from class path testing.

The build is dual. build.gradle and dependencies.gradle drive the Gradle build, and pom.xml at the root means Maven consumers and the Maven Central publication path are supported too. bnd.bnd at the root is OSGi bundle metadata, which tells you the jar is intended to be consumable in OSGi containers and not only as a plain class path jar. docs/ and the picocli.info homepage hold the documentation, and RELEASE-NOTES.md, CONTRIBUTING.md and SECURITY.md at the root are the standard project files.

## The Java version claim has drifted from the repository

The README says picocli requires at minimum Java 5, but is designed to facilitate the use of Java 8 lambdas, and that it is tested on all Java versions between 5 and 18-ea inclusive.

The repository's own layout does not match that picture. There are four separate test modules rather than one, and they are split by Java generation, including a module dedicated to Java 9 and later and a module dedicated to JPMS. JLine 3 is a separate shell integration module, and JLine 3 requires a modern baseline. picocli-codegen-tests-java9plus is split out as well.

Both facts are current, and neither is wrong in the way it first appears. The Java 5 claim describes the minimum the core library supports, which is a real and unusual commitment for a library of this scope and is likely to remain true. What has moved is the testing and tooling surface, which has clearly been reorganised around a modern floor. Reading the README sentence as a description of what the build exercises today is where it misleads.

The practical response is narrow. If you are on a current JDK, the parts that matter are the module you depend on and whether your runtime is inside the tested range, and the README's own upper bound of 18-ea is now well behind current long-term releases. The CI workflow linked from the badge is the place that reflects the actual matrix.

This is a good example of why the README is not the last word in a mature repository. The tags are the first word, and they are where the next section starts.

## Releases trail the commits

The three most recent releases are v4.7.7 from April 2025, v4.7.6 from May 2024, and v4.7.5 from August 2023. The release notes for 4.7.7 describe it as the eighty-sixth public release, which tells you the project ships reliably rather than occasionally.

What the dates tell you is that the cadence has slowed considerably. Roughly a year separates 4.7.5 and 4.7.6, roughly eleven months separates 4.7.6 and 4.7.7, and the last commit recorded in the repository is from August 2026. So the source has moved forward well past what is tagged, by more than a year of work.

Nothing about this is alarming on its own. A mature library that follows semantic versioning gains little from cutting frequent patch releases, and the absence of a new tag is not evidence of abandonment. But it does change what you should do when you pick a version.

If you want a released artifact, v4.7.7 is what Maven Central has, the badge links to it, and it is the version whose behaviour you can find other people writing about. If you want recent fixes, the source is ahead, and since picocli can be included as a single generated file rather than a jar, using current source is unusually low friction here. That is the payoff of the distribution model: tracking the repository instead of a release is a normal choice rather than a workaround.

What you should not do is assume the tag describes the current state of the code. For a library at this stage of its life, the repository is ahead of its version numbers, and reading the changelog before upgrading is worth the minute it costs.

## Design decisions that shape your code

Beyond the feature list, picocli makes a few choices that affect how your source is organised, and they are worth deciding on deliberately.

Annotations plus a programmatic API means you are not locked in. The annotation approach is concise, and the same model is reachable programmatically for the cases where you are generating a command tree at runtime rather than declaring it in source.

The model is inspectable. The @Spec annotation gives advanced use cases access to the picocli command object model, and the README describes custom parameter processing for the cases where the built-in option logic is not sufficient. Both are escape hatches, which is the right shape: use them when you need them rather than by default.

Executing a command takes a single line because the command class implements Runnable or Callable. The alternative, business logic in an annotated method, is a matter of taste and mostly a question of whether you want the class to be usable as a plain object outside the parser. Neither is enforced.

The README also points at the Command Line Interface Guidelines, a published set of conventions for how command line interfaces should behave. That is a small signal about the project's posture. The author is not only implementing parsing, but arguing for how command lines should look, and you can use that reference when you need to settle an argument about help text layout or option naming.

The last thing to weigh is the size of the commitment. picocli is a framework rather than a parser, and adopting the argument groups, subcommand tree and completion model changes how you structure the tool. For a small utility where you need three flags and a usage line, the standard library argument parser is a smaller answer. For anything users are expected to type regularly, the features you would otherwise build yourself are the reason to use this.

## Conclusion

picocli is the right default for a JVM command line tool when you want generated usage help, tab completion and typed options without adopting a whole application framework, and its single source file distribution removes the dependency question that otherwise slows adoption of a CLI library. Two things should shape how you pin it. The latest tagged release is v4.7.7 from April 2025 while commits continued into August 2026, so treat the repository as ahead of its releases and decide deliberately whether you want a published artifact or the current source. And the README still advertises a Java 5 minimum, which the repository's own test module layout no longer reflects; if you build on a modern JDK, verify the module you need still supports your runtime rather than taking the README's number at face value. Outside the JVM, none of this applies and you want a parser in your own language.

## FAQ

### How do I add picocli to a Java project?

The Maven coordinates are published to Maven Central under the group id info.picocli and the artifact id picocli, which the README badge links to. Alternatively, the picocli-codegen module generates a single source file you include directly, so your users do not need picocli as an external dependency at all.

### Can picocli applications be compiled to a native executable?

Yes. The README states that picocli-based applications can be compiled ahead of time to a GraalVM native image for fast startup and lower memory, and that a bundled annotation processor automatically Graal-enables your jar during compilation.

### Which Java versions does picocli support?

The README states a minimum of Java 5, with testing across Java versions from 5 up to 18-ea inclusive. The repository layout has moved on from that, with separate test modules for Java 9 and later and for JPMS, so check the CI workflow for the matrix the build actually exercises.

### Does picocli provide shell tab completion?

Yes. Autocompletion shows available options and subcommands interactively, and suggests values for options that declare completion candidates or use an enum type. Completion scripts can be generated for bash and zsh, and picocli-shell-jline2 and picocli-shell-jline3 modules provide JLine Completer implementations.

### Does picocli work with Spring Boot or Quarkus?

Both have dedicated paths. The repository ships a picocli-spring-boot-starter module, Quarkus offers a Command Mode with Picocli extension, and Micronaut has built-in support for picocli according to the README.

## Sources

- [License: Apache-2.0](https://github.com/remkop/picocli/blob/main/LICENSE)
- [Project website](https://picocli.info)
- [README](https://github.com/remkop/picocli/blob/main/README.md)
- [Releases](https://github.com/remkop/picocli/releases)
- [remkop/picocli on GitHub](https://github.com/remkop/picocli)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/remkop-picocli
