Nuru means "light" in Swahili - illuminating the path to your commands with clarity and simplicity.
dotnet add package TimeWarp.NuruTimeWarp.Nuru offers two first-class patterns for defining CLI commands:
Define routes inline with a fluent builder API:
using TimeWarp.Nuru;
NuruApp app = NuruApp.CreateBuilder(args)
.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);Define routes as classes with [NuruRoute] attributes:
using TimeWarp.Nuru;
// Program.cs - minimal setup
NuruApp app = NuruApp.CreateBuilder(args)
.Build();
return await app.RunAsync(args);
// AddCommand.cs - auto-discovered by source generator
[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;
}
}
}dotnet run -- add 15 25
# Output: 15 + 25 = 40β Full Getting Started Guide
| Feature | Description | Learn More |
|---|---|---|
| π― Web-Style Routing | Familiar "deploy {env} --version {tag}" syntax |
Routing Guide |
| β‘ Dual Approach | Mix Direct (fast) + Mediator (structured) | 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 |
| π¨ Colored Output | Fluent ANSI colors without Spectre.Console | Terminal Abstractions |
- Getting Started Guide - Build your first CLI app in 5 minutes
- Use Cases - Greenfield apps & progressive enhancement patterns
- Architecture Choices - Choose Direct, Mediator, or Mixed
- Routing Patterns - Complete route syntax reference
- Roslyn Analyzer - Compile-time validation
- Logging System - Structured logging setup
- Auto-Help - Automatic help generation
- Output Handling - stdout/stderr best practices
- Terminal Abstractions - Testable I/O & colored output
- MCP Server - AI-powered development assistance
- Deployment Guide - Native AOT, runfiles, distribution
- Best Practices - Patterns for maintainable CLIs
- Performance Benchmarks - Detailed performance metrics
- Supported Types - Complete type reference
- API Documentation - Technical reference
Build modern command-line tools from scratch:
NuruApp app = NuruApp.CreateBuilder(args)
.Map("deploy {env} --version {tag?}")
.WithHandler((string env, string? tag) => Deploy(env, tag))
.AsCommand()
.Done()
.Map("backup {source} {dest?} --compress")
.WithHandler((string source, string? dest, bool compress) => Backup(source, dest, compress))
.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:
- 01-calc-delegate.cs - Fluent DSL approach (inline handlers)
- 02-calc-commands.cs - Endpoints routes pattern (testable, DI)
- 03-calc-mixed.cs - Mixed approach (both patterns together)
./samples/02-calculator/03-calc-mixed.cs add 10 20 # Fluent DSL: inline
./samples/02-calculator/03-calc-mixed.cs factorial 5 # Endpoints: structuredAOT 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 |
| Mediator (AOT) | Moderate | 0.42s π | 4.8 MB |
Native AOT is 88-93% faster than JIT β Full Performance Benchmarks
Install the MCP server for AI assistance:
dotnet tool install --global TimeWarp.Nuru.McpGet instant help in Claude Code, Roo Code, or Continue:
- Validate route patterns before writing code
- Generate handler code automatically
- Get syntax examples on demand
- Real-time error guidance
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.fishSupports:
- β
Command completion (
deploy,status) - β
Option completion (
--version,--force) - β
Short option aliases (
-v,-f) - β All 4 major shells (bash, zsh, PowerShell, fish)
See completion-example for a complete working example.
We welcome contributions! See CONTRIBUTING.md for details.
For Contributors:
- Developer Documentation - Architecture and design
- Standards - Coding conventions
This project is licensed under the Unlicense - see the license file for details.
Ready to build powerful CLI applications?
Get Started in 5 Minutes β’ View Examples β’ Read the Docs