Route-based CLI framework for .NET - batteries included with telemetry, REPL, and shell completion
$ dotnet add package TimeWarp.NuruNuru means "light" in Swahili - illuminating the path to your commands with clarity and simplicity.
dotnet add package TimeWarp.Nuru
TimeWarp.Nuru offers two patterns for defining CLI commands. Start with the Endpoint DSL for structured apps, or Fluent DSL for quick scripts.
Define routes as classes with [NuruRoute] attributes:
using TimeWarp.Nuru;
[NuruRoute("add", Description = "Add two numbers together")]
public sealed class AddCommand : ICommand<Unit>
{
[Parameter(Order = 0)] public double X { get; set; }
[Parameter(Order = 1)] public double Y { get; set; }
public sealed class Handler : ICommandHandler<AddCommand, Unit>
{
public ValueTask<Unit> Handle(AddCommand command, CancellationToken ct)
{
Console.WriteLine($"{command.X} + {command.Y} = {command.X + command.Y}");
return default;
}
}
}
// In your main file:
NuruApp app = NuruApp.CreateBuilder()
.DiscoverEndpoints()
.Build();
return await app.RunAsync(args);
Define routes inline with a fluent builder API:
using TimeWarp.Nuru;
NuruApp app = NuruApp.CreateBuilder()
.Map("add {x:double} {y:double}")
.WithHandler((double x, double y) => Console.WriteLine($"{x} + {y} = {x + y}"))
.AsCommand()
.Done()
.Build();
return await app.RunAsync(args);
dotnet run -- add 15 25
# Output: 15 + 25 = 40
| Feature | Description | Learn More |
|---|---|---|
| 🎯 Web-Style Routing | Familiar "deploy {env} --version {tag}" syntax | Routing Guide |
| 📦 Endpoint DSL | Class-based commands with DiscoverEndpoints() auto-discovery | Architecture Choices |
| 🔧 Fluent DSL | Inline routes with .Map().WithHandler().Done() chain | Architecture Choices |
| 🛡️ Roslyn Analyzer | Catch route errors at compile-time | Analyzer Docs |
| ⌨️ Shell Completion | Tab completion for bash, zsh, PowerShell, fish | Shell Completion |
| 🤖 MCP Server | AI-assisted development with Claude | MCP Server Guide |
| 📊 Logging Package | Zero-overhead structured logging | Logging Docs |
| 🚀 Native AOT | Zero warnings, 3.3 MB binaries, instant startup | Deployment Guide |
| 🔒 Type-Safe Parameters | Automatic type conversion and validation | Supported Types |
| 📖 Auto-Help | Generate help from route patterns | Auto-Help Feature |
| 🎨 Rich Terminal | Colors, tables, panels, rules via TimeWarp.Terminal | Terminal Guide |
Build modern command-line tools from scratch:
myapp/
├── calculator.cs # Single runfile - just 5 lines
└── endpoints/
├── add-command.cs
├── factorial-command.cs
└── ...
Endpoint DSL approach (class-based, organized by file):
// In endpoints/add-command.cs
[NuruRoute("add", Description = "Add two numbers")]
public sealed class AddCommand : ICommand<Unit>
{
[Parameter] public double X { get; set; }
[Parameter] public double Y { get; set; }
public sealed class Handler : ICommandHandler<AddCommand, Unit>
{
public ValueTask<Unit> Handle(AddCommand c, CancellationToken ct)
{
Console.WriteLine($"{c.X} + {c.Y} = {c.X + c.Y}");
return default;
}
}
}
Fluent DSL approach (inline definitions):
NuruApp.CreateBuilder()
.Map("deploy {env} --version {tag?}")
.WithHandler((string env, string? tag) => Deploy(env, tag))
.AsCommand()
.Done()
.Build();
Wrap existing CLIs to add auth, logging, or validation:
NuruApp app = NuruApp.CreateBuilder(args)
.Map("deploy prod")
.WithHandler(async () =>
{
if (!await ValidateAccess()) return 1;
return await Shell.ExecuteAsync("existing-cli", "deploy", "prod");
})
.AsCommand()
.Done()
.Map("{*args}")
.WithHandler(async (string[] args) => await Shell.ExecuteAsync("existing-cli", args))
.AsCommand()
.Done()
.Build();
→ Detailed Use Cases with Examples
Calculator Samples - Three complete implementations you can run now:
./samples/02-calculator/01-calc-endpoints.cs add 10 20 # Endpoint DSL: structured
./samples/02-calculator/02-calc-fluent.cs factorial 5 # Fluent DSL: inline
AOT Example - Native AOT compilation with source generators
| Implementation | Memory | Speed (37 tests) | Binary Size |
|---|---|---|---|
| Direct (JIT) | ~4 KB | 2.49s | N/A |
| Direct (AOT) | ~4 KB | 0.30s 🚀 | 3.3 MB |
| Endpoints (AOT) | Moderate | 0.42s 🚀 | 4.8 MB |
Native AOT is 88-93% faster than JIT → Full Performance Benchmarks
For AI agents: Load the built-in Nuru Skill for instant access to:
💡 Tip: No MCP installation needed - the skill provides all essential patterns.
For MCP Server: Install for Claude Code, Roo Code, or Continue:
dotnet tool install --global TimeWarp.Nuru.Mcp
Get instant help:
Enable tab completion for your CLI with one line of code:
NuruApp app = NuruApp.CreateBuilder(args)
.Map("deploy {env} --version {tag}")
.WithHandler((string env, string tag) => Deploy(env, tag))
.AsCommand()
.Done()
.Map("status")
.WithHandler(() => ShowStatus())
.AsQuery()
.Done()
.EnableStaticCompletion() // ← Add this
.Build();
Generate completion scripts for your shell:
# Bash
./myapp --generate-completion bash >> ~/.bashrc
# Zsh
./myapp --generate-completion zsh >> ~/.zshrc
# PowerShell
./myapp --generate-completion powershell >> $PROFILE
# Fish
./myapp --generate-completion fish > ~/.config/fish/completions/myapp.fish
Supports:
deploy, status)--version, --force)-v, -f)See completion-example for a complete working example.
We welcome contributions! See CONTRIBUTING.md for details.
For Contributors:
This project is licensed under the Unlicense - see the license file for details.
Ready to build powerful CLI applications?