CLI framework for C++: cppcli — creating console applications

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 framework for C++: cppcli — creating powerful console applications



Developing console interfaces (CLI) in C++ often requires manual argument parsing, flag handling, and command organization. The cppcli library provides a ready-made framework for quickly creating professional CLI applications. It allows you to focus on business logic rather than input/output infrastructure. In this article, we will break down the key features of cppcli, provide code examples, and show how to integrate it into your project.



Key features of cppcli



  • Declarative command definition — each command is described as a separate class or lambda function.
  • Automatic argument parsing — support for positional, named arguments, and flags.
  • Colored output and formatting — built-in utilities for styled output (ANSI colors, tables, progress bars).
  • Validation and help — automatic generation of help messages and validation of required arguments.
  • Extensibility — support for custom argument types and middleware.


Quick start: installation and first example



cppcli is distributed as a header-only library. To install, clone the repository or use CMake FetchContent. Integration into a project:



#include <cppcli/cli.h>#include <iostream>

int main(int argc, char* argv[]) { cppcli::App app("My application", "1.0.0"); app.run(argc, argv); return 0;}


This is the minimal skeleton. Now let's add a greet command that takes a user name.



Example: command with arguments



#include <cppcli/cli.h>

int main(int argc, char* argv[]) { cppcli::App app("Greeter", "1.0.0");

app.command("greet", "Greets the user") .argument<std::string>("name", "User name") .action([](const cppcli::Args& args) { std::string name = args.get<std::string>("name"); std::cout << "Hello, " << name << "!"; });

app.run(argc, argv); return 0;}


Run: ./app greet Ivan will output Hello, Ivan!. If the argument is not specified, cppcli will output an error and help.



Flags and optional parameters



Let's add a --formal flag for a formal greeting:



app.command("greet", "Greets the user")    .argument<std::string>("name", "Name")    .flag("--formal", "-f", "Formal greeting")    .action([](const cppcli::Args& args) {        std::string name = args.get<std::string>("name");        bool formal = args.get<bool>("formal");        if (formal)            std::cout << "Greetings, " << name << "!";        else            std::cout << "Hello, " << name << "!";    });


Now ./app greet Ivan --formal will output Greetings, Ivan!.



Nested commands and subcommands



cppcli supports a tree-like command structure. For example, for a project management utility:



app.command("project", "Project management")    .command("create", "Create a project")        .argument<std::string>("name", "Project name")        .action([](const cppcli::Args& args) {            std::cout << "Project created: " << args.get<std::string>("name") << "";        })    .command("delete", "Delete a project")        .argument<std::string>("name", "Project name")        .flag("--force", "Without confirmation")        .action([](const cppcli::Args& args) {            // deletion logic        });


Call: ./app project

Recommendations