CLI frameworks for C# (.NET): System.CommandLine and Cocona
Creating console applications (CLI) in C# has long been associated with manual parsing of command-line arguments via string[] args and cumbersome conditional constructs. However, with the development of the .NET ecosystem, specialized frameworks have emerged that handle the routine: argument parsing, help generation, validation, and even dependency injection (DI). In this article, we will look at two of the most popular approaches: the official System.CommandLine from Microsoft and the lightweight but powerful Cocona.
Both tools allow you to write clean, declarative code that is easy to maintain and test. You will learn how to quickly add them to a project, define commands and arguments, and see real code examples.
1. System.CommandLine
System.CommandLine is an official library from Microsoft, included in the .NET SDK (starting from .NET 6). It provides a full set of features for building complex CLI applications: nested commands, Tab autocomplete, validation, asynchronous handlers, and help generation.
Installation
Add the package via NuGet:
dotnet add package System.CommandLine --version 2.0.0-beta4.22272.1Example: calculator with two operations
Let's create a simple application that accepts the add or multiply command with two numbers:
using System.CommandLine;
// Define the root commandvar rootCommand = new RootCommand("Simple calculator");
// Create the "add" subcommandvar addCommand = new Command("add", "Add two numbers");var addXOption = new Option<int>("--x", "First number") { IsRequired = true };var addYOption = new Option<int>("--y", "Second number") { IsRequired = true };addCommand.AddOption(addXOption);addCommand.AddOption(addYOption);
addCommand.SetHandler((x, y) =>{ Console.WriteLine($"Addition result: {x + y}");}, addXOption, addYOption);
// Create the "multiply" subcommandvar multiplyCommand = new Command("multiply", "Multiply two numbers");var multXOption = new Option<int>("--x", "First number") { IsRequired = true };var multYOption = new Option<int>("--y", "Second number") { IsRequired = true };multiplyCommand.AddOption(multXOption);multiplyCommand.AddOption(multYOption);
multiplyCommand.SetHandler((x, y) =>{ Console.WriteLine($"Multiplication result: {x * y}");}, multXOption, multYOption);
// Add commands to the rootrootCommand.AddCommand(addCommand);rootCommand.AddCommand(multiplyCommand);
// Runawait rootCommand.InvokeAsync(args);Running the application:
dotnet run -- add --x 5 --y 3# Output: Addition result: 8
dotnet run -- multiply --x 4 --y 7# Output: Multiplication result: 28Key features of System.CommandLine
- Autocomplete — built-in support for Tab completion in bash and PowerShell.
- Help generation — the
--helpflag automatically generates a description of all commands and options. - Validation — you can set required parameters, value ranges, and custom checks.
- Asynchrony — handlers support
async Task. - Testing — easy to write unit tests using
TestConsole.
2. Cocona
Cocona is an alternative framework that offers a more concise syntax thanks to attributes and automatic parameter binding. It is ideal for small and medium-sized projects where development speed is important. Cocona supports DI, middleware, and nested commands.
Installation
dotnet add package Co Also in library
HTTP Client for JavaScript (Node.js): Top Libraries for Working with API
Working with Excel in Kotlin: Apache POI Libraries and Kotlin Wrappers
Working with Dates in PHP: Overview of Libraries and Tools
Machine Learning in Kotlin: Overview of Libraries for Data Science and ML
NaturalLanguage for Swift: Complete Guide with Examples