System.CommandLine
2.0.0
Prefix Reserved
dotnet add package System.CommandLine --version 2.0.0
NuGet\Install-Package System.CommandLine -Version 2.0.0
<PackageReference Include="System.CommandLine" Version="2.0.0" />
<PackageVersion Include="System.CommandLine" Version="2.0.0" />
<PackageReference Include="System.CommandLine" />
paket add System.CommandLine --version 2.0.0
#r "nuget: System.CommandLine, 2.0.0"
#:package System.CommandLine@2.0.0
#addin nuget:?package=System.CommandLine&version=2.0.0
#tool nuget:?package=System.CommandLine&version=2.0.0
System.CommandLine
System.CommandLine provides robust support for command-line parsing, invocation, and shell completions in .NET applications. It supports both POSIX and Windows conventions, making it easy to build professional command-line interfaces.
Getting Started
Basic Command
Here's a simple "Hello World" command-line application:
using System.CommandLine;
RootCommand rootCommand = new("Sample command-line app");
Option<string> nameOption = new("--name", "-n")
{
Description = "Your name"
};
rootCommand.Options.Add(nameOption);
rootCommand.SetAction(parseResult =>
{
string name = parseResult.GetValue(nameOption);
Console.WriteLine($"Hello, {name ?? "World"}!");
});
return rootCommand.Parse(args).Invoke();
In this example, we create a RootCommand, add an option for the user's name, and define an action that prints a greeting. The RootCommand is a special kind of Command that comes with a few predefined behaviors:
- It discovers its name automatically from the currently-running application
- It automatically provides
--helpand--versionoptions and default behaviors for them - It provides a default integration with
dotnet-suggestfor dynamic shell completions
You can always override or customize these behaviors as needed on a RootCommand, or create your own top-level Command instead.
Commands with Arguments
Arguments are values passed directly to commands without option names:
var fileArgument = new Argument<FileInfo>("file")
{
Description = "The file to process"
};
var processCommand = new Command("process", "Process a file");
processCommand.Arguments.Add(fileArgument);
processCommand.SetAction(parseResult =>
{
FileInfo file = parseResult.GetValue(fileArgument);
Console.WriteLine($"Processing {file.FullName}");
});
var rootCommand = new RootCommand();
rootCommand.Subcommands.Add(processCommand);
Options with Default Values
Options can have default values and validation:
var rootCommand = new RootCommand();
var delayOption = new Option<int>("--delay", "-d")
{
Description = "Delay in milliseconds",
DefaultValueFactory = _ => 1000
};
delayOption.Validators.Add(result =>
{
if (result.GetValueOrDefault<int>() < 0)
{
result.AddError("Delay must be non-negative");
}
});
rootCommand.Options.Add(delayOption);
Subcommands
Build complex CLI applications with nested commands:
var rootCommand = new RootCommand("My application");
var configCommand = new Command("config", "Configure the application");
var configSetCommand = new Command("set", "Set a configuration value");
var configGetCommand = new Command("get", "Get a configuration value");
var keyOption = new Option<string>("--key")
{
Description = "Configuration key"
};
var valueOption = new Option<string>("--value")
{
Description = "Configuration value"
};
configSetCommand.Options.Add(keyOption);
configSetCommand.Options.Add(valueOption);
configGetCommand.Options.Add(keyOption);
configCommand.Subcommands.Add(configSetCommand);
configCommand.Subcommands.Add(configGetCommand);
rootCommand.Subcommands.Add(configCommand);
// Usage: myapp config set --key "apiUrl" --value "https://api.example.com"
// Usage: myapp config get --key "apiUrl"
Using Options in Command Actions
Access option values through the ParseResult:
var connectionOption = new Option<string>("--connection")
{
Description = "Database connection string"
};
var timeoutOption = new Option<int>("--timeout")
{
Description = "Timeout in seconds",
DefaultValueFactory = _ => 30
};
var verboseOption = new Option<bool>("--verbose")
{
Description = "Enable verbose output"
};
rootCommand.Options.Add(connectionOption);
rootCommand.Options.Add(timeoutOption);
rootCommand.Options.Add(verboseOption);
rootCommand.SetAction(parseResult =>
{
var connection = parseResult.GetValue(connectionOption);
var timeout = parseResult.GetValue(timeoutOption);
var verbose = parseResult.GetValue(verboseOption);
Console.WriteLine($"Connection: {connection}");
Console.WriteLine($"Timeout: {timeout}");
Console.WriteLine($"Verbose: {verbose}");
});
Shell Completions
Enable tab completion for your CLI:
// Completions are automatically available for all commands, options, and arguments
var rootCommand = new RootCommand("My app with completions");
var fileOption = new Option<FileInfo>("--file")
{
Description = "The file to process"
};
// Add custom completions using CompletionSources
fileOption.CompletionSources.Add(ctx =>
// hard-coded list of files
["file1.txt", "file2.txt", "file3.txt" ]
);
// Or add simple string suggestions
fileOption.CompletionSources.Add("option1", "option2", "option3");
rootCommand.Options.Add(fileOption);
Users can then easily trigger your completions using dotnet-suggest:
> dotnet tool install -g dotnet-suggest
> dotnet suggest script bash > ~/.bashrc
> dotnet tool install -g dotnet-suggest
> dotnet suggest script powershell >> $PROFILE
Once dotnet-suggest is installed, you can register your app with it for completions support:
> dotnet-suggest register --command-path /path/to/myapp
Alternatively, you can create your own commands for completion generation and instruct users on how to set them up.
Async Command Handlers
Support for asynchronous operations:
var urlOption = new Option<string>("--url")
{
Description = "The URL to fetch"
};
rootCommand.Options.Add(urlOption);
rootCommand.SetAction(async (parseResult, cancellationToken) =>
{
var url = parseResult.GetValue(urlOption);
if (url != null)
{
using var client = new HttpClient();
var response = await client.GetStringAsync(url, cancellationToken);
Console.WriteLine(response);
}
});
// Or return an exit code:
rootCommand.SetAction(async (parseResult, cancellationToken) =>
{
// Your async logic here
return await Task.FromResult(0); // Return exit code
});
Notable Changes Since v2.0.0-beta7
New Features
- Improved Help System: Enhanced
HelpActionto allow users to provide customMaxWidthfor help text formatting (#2635). Note that if you create custom Help or Version actions, you'll want to setClearsParseErrorstotrueto ensure that invoking those features isn't treated like an error by the parser. Task<int>Support: AddedSetActionoverload forTask<int>return types (#2634)- Detect Implicit Arguments: Added the
ArgumentResult.Implicitproperty for better argument handling (#2622, #2625) - Performance Improvements: Reduced reflection usage throughout the library for better performance (#2662)
Bug Fixes
- Fixed issue #2128: Resolved command parsing edge cases (#2656)
- Fixed issue #2257: Corrected argument validation behavior
- Fixed issue #2589: Improved error message clarity (#2654)
- Fixed issue #2591: Resolved option parsing inconsistencies (#2644)
- Fixed issue #2622: Enhanced implicit argument support (#2625)
- Fixed issue #2628: Corrected help text formatting issues
- Fixed issue #2634: Added missing Task<int> action support
- Fixed issue #2640: Resolved completion suggestions for nested commands (#2646)
Breaking Changes
- Default value handling for
ProcessTerminationTimeouthas been re-added (#2672) - Some internal APIs have been refactored to reduce reflection usage (#2662)
Other Improvements
- Updated to .NET 10.0 RC1 compatibility
- Improved memory usage and performance optimizations
- Better handling of complex command hierarchies
Documentation
For comprehensive documentation, tutorials, and API reference, visit:
- Microsoft Learn Documentation - Complete guides and API reference
- GitHub Repository - Source code, samples, and issues
Framework Support
- .NET 8.0+ - Full feature support with trimming and AOT compilation
- .NET Standard 2.0 - Compatible with .NET Framework 4.6.1+, .NET Core 2.0+
License
This package is licensed under the MIT License.
Contributing
We welcome contributions! Please see our Contributing Guide for details.
Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- System.Memory (>= 4.5.5)
-
net8.0
- No dependencies.
NuGet packages (262)
Showing the top 5 NuGet packages that depend on System.CommandLine:
| Package | Downloads |
|---|---|
|
System.CommandLine.NamingConventionBinder
This package provides command handler support for System.CommandLine performs parameter and model binding by matching option and argument names to parameter and property names. |
|
|
System.CommandLine.Rendering
This package provides support for structured command line output rendering. Write code once that renders correctly in multiple output modes, including System.Console, virtual terminal (using ANSI escape sequences), and plain text. |
|
|
System.CommandLine.DragonFruit
This package includes the experimental DragonFruit app model for System.CommandLine, which allows you to create a command line application using only a Main method while getting support for complex type binding, error reporting, help, shell completions, and more. |
|
|
System.CommandLine.Hosting
This package provides support for using System.CommandLine with Microsoft.Extensions.Hosting. |
|
|
HotChocolate.AspNetCore.CommandLine
This package contains the command line extensions for HotChocolate |
GitHub repositories (309)
Showing the top 20 popular GitHub repositories that depend on System.CommandLine:
| Repository | Stars |
|---|---|
|
microsoft/PowerToys
Microsoft PowerToys is a collection of utilities that help you customize Windows and streamline everyday tasks
|
|
|
PowerShell/PowerShell
PowerShell for every system!
|
|
|
dotnet/aspnetcore
ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
|
|
|
DevToys-app/DevToys
A Swiss Army knife for developers.
|
|
|
microsoft/semantic-kernel
Integrate cutting-edge LLM technology quickly and easily into your apps
|
|
|
BeyondDimension/SteamTools
🛠「Watt Toolkit」是一个开源跨平台的多功能 Steam 工具箱。
|
|
|
dotnet/roslyn
The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
|
|
|
dotnet/runtime
.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
|
|
|
MaterialDesignInXAML/MaterialDesignInXamlToolkit
Google's Material Design in XAML & WPF, for C# & VB.Net.
|
|
|
duplicati/duplicati
Store securely encrypted backups in the cloud!
|
|
|
winsw/winsw
A wrapper executable that can run any executable as a Windows service, in a permissive license.
|
|
|
nilaoda/BBDown
Bilibili Downloader. 一个命令行式哔哩哔哩下载器.
|
|
|
MonoGame/MonoGame
One framework for creating powerful cross-platform games.
|
|
|
dotnet/orleans
Cloud Native application framework for .NET
|
|
|
gui-cs/Terminal.Gui
Cross Platform Terminal UI toolkit for .NET
|
|
|
unoplatform/uno
Open-source platform for building cross-platform native Mobile, Web, Desktop and Embedded apps quickly. Create rich, C#/XAML, single-codebase apps from any IDE. Hot Reload included! 90m+ NuGet Downloads!!
|
|
|
git-ecosystem/git-credential-manager
Secure, cross-platform Git credential storage with authentication to GitHub, Azure Repos, and other popular Git hosting services.
|
|
|
BartoszCichecki/LenovoLegionToolkit
Lightweight Lenovo Vantage and Hotkeys replacement for Lenovo Legion laptops.
|
|
|
nilaoda/N_m3u8DL-RE
Cross-Platform, modern and powerful stream downloader for MPD/M3U8/ISM. English/简体中文/繁體中文.
|
|
|
Azure/azure-sdk-for-net
This repository is for active development of the Azure SDK for .NET. For consumers of the SDK we recommend visiting our public developer docs at https://learn.microsoft.com/dotnet/azure/ or our versioned developer docs at https://azure.github.io/azure-sdk-for-net.
|
| Version | Downloads | Last Updated |
|---|---|---|
| 2.0.0 | 19,219 | 11/11/2025 |
| 2.0.0-rc.2.25502.107 | 151,839 | 10/14/2025 |
| 2.0.0-rc.1.25451.107 | 271,474 | 9/9/2025 |
| 2.0.0-beta7.25380.108 | 188,462 | 8/12/2025 |
| 2.0.0-beta6.25358.103 | 176,139 | 7/15/2025 |
| 2.0.0-beta5.25306.1 | 338,770 | 6/19/2025 |
| 2.0.0-beta4.22272.1 | 32,408,603 | 6/2/2022 |
| 2.0.0-beta3.22114.1 | 2,532,847 | 2/17/2022 |
| 2.0.0-beta3.22111.2 | 128,658 | 2/12/2022 |
| 2.0.0-beta3.22106.2 | 34,197 | 2/6/2022 |
| 2.0.0-beta3.22103.3 | 8,183 | 2/4/2022 |
| 2.0.0-beta2.21617.1 | 792,771 | 12/17/2021 |
| 2.0.0-beta1.21308.1 | 4,075,428 | 7/2/2021 |
| 2.0.0-beta1.21216.1 | 2,526,528 | 4/17/2021 |
| 2.0.0-beta1.20574.7 | 2,692,720 | 11/25/2020 |
| 2.0.0-beta1.20371.2 | 6,220,806 | 7/23/2020 |
| 2.0.0-beta1.20214.1 | 688,682 | 4/15/2020 |
| 2.0.0-beta1.20213.1 | 237,858 | 4/13/2020 |
| 2.0.0-beta1.20158.1 | 4,237,613 | 3/8/2020 |
| 2.0.0-beta1.20104.2 | 499,675 | 2/7/2020 |
| 2.0.0-beta1.20071.2 | 447,068 | 1/22/2020 |
| 0.3.0-alpha.20070.2 | 45,600 | 1/21/2020 |
| 0.3.0-alpha.20054.1 | 209,495 | 1/5/2020 |