Blokyk.StarKid 0.5.0

dotnet add package Blokyk.StarKid --version 0.5.0
                    
NuGet\Install-Package Blokyk.StarKid -Version 0.5.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Blokyk.StarKid" Version="0.5.0">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Blokyk.StarKid" Version="0.5.0" />
                    
Directory.Packages.props
<PackageReference Include="Blokyk.StarKid">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Blokyk.StarKid --version 0.5.0
                    
#r "nuget: Blokyk.StarKid, 0.5.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Blokyk.StarKid@0.5.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Blokyk.StarKid&version=0.5.0
                    
Install as a Cake Addin
#tool nuget:?package=Blokyk.StarKid&version=0.5.0
                    
Install as a Cake Tool

StarKid

[ Quick Start ] | [ Tutorial ] | [ Overview ] | [ Docs ]


A C# source generator to create command-line apps from a simple, code-based description (now with 80% less boilerplate!).

What can it actually do?

StarKid allows you to write code that matches perfectly your command line interface's structure, by using nesting to represent your CLI's hierarchy of verbs and subcommands.

It also includes a bunch of mechanisms to make parsing and validating options/args easier, so you never have to string-type anything, you can simply use the appropriate type for everything instead of writing walls of if-then-throws at the start of every method.

Getting started 🚀

StarKid is just like most other source generators and requires no additional dependency. You can install it just like a normal package, with:

dotnet add package Blokyk.StarKid

That's it! For a quick tutorial, check out Your first app with StarKid, or have a look through the TL;DR docs below. If you want to deep-dive directly in, you can check out the overview and the rest of the docs folder

TL;DR docs 📖

using StarKid;

[CommandGroup("my-app")]
public static class MyApp {
    [Option("verbose", 'v')]
    public bool ShouldBeVerbose { get; set; }

    [Command("greet")]
    // ./my-app greet <name> [--greeting greetingPhrase]
    public void Greet(string name, [Option("greeting", 'g')] string greetingPhrase = "Hello, ") {
        if (ShouldBeVerbose)
            Console.Error.WriteLine($"Running command 'greet' with name '{name}' and phrase '{greetingPhrase}'");

        Console.WriteLine(greetingPhrase + name + "!")
    }
}
  • Commands are represented by methods marked with [Command], groups of commands by (static) classes marked with [CommandGroup].

  • By nesting classes inside others, you can have a command group "inside" another group, which acts as a subgroup to its parent.

  • The outmost [CommandGroup] class is the root group, which basically defines the CLI; it is only special in that there can't be multiple root groups (since you can't have multiple CLIs inside a single assembly).

  • Command options are declared by adding [Option] to a parameter. Any other parameter will be treated as a mandatory argument.

  • An [Option] whose type is bool will be treated as a flag.

  • Using [Option] on a field or property (with a set accessor) declares that option for the whole group.

  • Just like you can't have methods outside of classes, you can't have [Command]s outside of [CommandGroup]s.

For more information, check out Your first app with StarKid and StarKid overview.

...why tho?

While rewriting lotus's command line interface to use System.CommandLine, I found myself looking at System.CommandLine.DragonFruit, a generator that makes writing basic CLIs absolutely effortless.

However, after looking at its implementation, I was slightly disappointed to find that it was basically just a redirect to reflection-based parsing. Don't get me wrong, I heavily respect the people behind that project, both for the simplicity of DragonFruit and the flexibility of System.CommandLine[^1], but it did feel like there was a gap to be filled there.

[^1]: It also tries to follow POSIX standards and conventions which is absolutely impressive in its right.

I wanted to try my hand at writing a source generator, as well as having a slightly less complex/obscure mechanism for lotus's CLI. So I started writing, not expecting to actually do anything useful, let alone have an actual generator. And yet here we are.

One thing to note is that this generator does not simply replace your declaration with calls to the System.CommandLine library, it is a completely separate thing. Unfortunately, right now a few tools in the dotnet environment rely on System.CLI's niceties, which means for now some features you might be used to will be unavailable; for example, you won't get compatibility with dotnet-suggest, or any kind of "debug-mode" like in System.CLI. As I've stated above, my initial goal was simply to get a reflection- and overhead-free alternative to that library, and given how tightly integrated dotnet-suggest is with it, I can't make any promises as to whether this will be supported in any future versions. However, it is a tool I use a lot given my usage of the terminal, so I'll definitely try to investigate it in my free time.

For now, I don't actually plan on maintaining this any further than I need to for my personal projects, but I'm completely open to hearing about any issues or requests you might have, so feel free to create an issue/PR and I'll try to take a look at it!

Disclaimer ⚠️

You probably shouldn't actually use this for anything serious. While I've put a lot of effort into it, it is still pretty brittle in some cases; and although StarKid's design has gone through multiple iterations, it is fairly opinionated, goes against some of C#'s coding conventions, and can quickly lead to unmaintainable code if not planned carefully. I personally encourage partial classes split into files and folders reflecting your CLI's structure.

In addition, it is not fit for every case or app in the world: it heavily discourages "one root command, a thousand options"-kind of CLI. If you're trying to write a GCC-style CLI with a thousand different flags, this is probably not the library for you.

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.5.0 141 9/9/2025
0.4.0 141 9/9/2025