What it is
CLI11 is a C++11 header-only library for parsing command line arguments. It provides an expressive, modern C++ API for handling flags, options, subcommands, and configuration files with minimal boilerplate.
CLI11 makes it simple to define options, flags, and subcommands while handling validation, default values, and automatic help text generation.
Installation
find_package(CLI11 CONFIG REQUIRED)Getting started
The smallest useful thing you can do with it, and what each part means.
#include <CLI/CLI.hpp>
#include <iostream>
int main(int argc, char** argv) {
CLI::App app{"My Program"};
int count;
app.add_option("-c,--count", count, "Number of iterations");
bool verbose = false;
app.add_flag("-v,--verbose", verbose, "Enable verbose output");
CLI11_PARSE(app, argc, argv);
std::cout << "Count: " << count << " Verbose: " << verbose << std::endl;
return 0;
}Advanced usage
Where the library earns its place over a simpler alternative.
CLI::App app{"Main app"};
auto* sub = app.add_subcommand("convert", "Convert files");
std::string input;
sub->add_option("input", input, "Input file")->required();
CLI11_PARSE(app, argc, argv);
if (*sub) {
std::cout << "Converting file: " << input << std::endl;
}int threads = 4;
app.add_option("-t,--threads", threads, "Number of threads")->check(CLI::PositiveNumber);
std::string config;
app.set_config("config.ini", true);
app.add_option("--config", config, "Config file");enum class Mode { fast, slow };
Mode mode;
app.add_option("--mode", mode)
->transform(CLI::CheckedTransformer({{"fast", Mode::fast}, {"slow", Mode::slow}}));Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- Unrecognized flag or option
- CLI11 automatically provides helpful error messages and usage text.
- Required option missing
- Mark options as `required()` only when absolutely necessary.
- Invalid type conversion
- Use `transform` or `check` validators to prevent invalid input.
Best practices
- Use descriptive names for flags and options to improve usability.
- Leverage validation checks to enforce correct argument values.
- Group related commands into subcommands for structured CLI design.
- Provide default values where applicable for a smoother user experience.
- Use `app.set_config()` to combine command-line and config file parsing.
Background
Why it exists, and what it was reacting to.
CLI11 was created by Henry Schreiner to modernize C++ command line parsing. It was designed to be lightweight, flexible, and integrate naturally with C++11 and newer standards. Today, it is widely used in scientific software, tools, and utilities where robust command-line interfaces are needed.
