NSmithy

August 25, 2026 · View on GitHub

CI Docs NuGet .NET 10 License Smithy CLI

Preview: NSmithy is in preview; expect some API changes before 1.0. Protocol implementations are not yet on par with the Smithy reference implementations.

NSmithy

Docs · Examples · Design Docs · smithy.io

NSmithy is a .NET toolkit that turns a Smithy model into idiomatic C# at build time.

Features

  • Contract-first: The Smithy model is the source of truth. NSmithy generates C# model types, clients, and ASP.NET Core server stubs from it.
  • Protocol-agnostic: The same model can target multiple protocols; switching protocols requires no changes to client or server code.
  • Part of the Smithy ecosystem: A .NET service built with NSmithy can be called from clients generated for Java, TypeScript, Python, Go, Rust, Swift, and more, and vice versa.
  • Protocol support: REST JSON, REST XML, AWS JSON, AWS Query / EC2 Query, RPC v2 CBOR, and gRPC.
  • Streaming support: Event streaming, bidirectional streaming, and streaming blob payloads.
  • Smithy-native architecture: Follows Smithy's official code generator guidance.
  • Conformance-tested: Tested against official Smithy, AWS, and alloy conformance suites.

Quick Start

Start with a Smithy model in a contracts project:

@restJson1
service HelloService {
    version: "1.0.0"
    operations: [SayHello]
}

@http(method: "POST", uri: "/hello", code: 200)
operation SayHello {
    input := {
        @required
        name: String
    }
    output := {
        @required
        message: String
    }
}

dotnet build runs NSmithy codegen and produces the C# model types, generated ASP.NET Core server hooks, and a typed client. Implement the generated handler on the server:

using Hello.World;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHelloServiceHandler<HelloHandler>();

var app = builder.Build();
app.MapHelloService();
app.Run();

internal sealed class HelloHandler : IHelloServiceHandler
{
    public Task<SayHelloOutput> SayHelloAsync(
        SayHelloInput input,
        CancellationToken cancellationToken = default
    ) =>
        Task.FromResult(new SayHelloOutput($"Hello, {input.Name}!"));
}

Then call it through the generated client from another .NET project:

using Hello.World;

var client = new HelloServiceClient(new Uri("http://localhost:5000"));
var response = await client.SayHelloAsync(new SayHelloInput("world"));
Console.WriteLine(response.Message); // Hello, world!

See the Quick Start guide for the full walkthrough.

Development

The recommended way to work on this repo is with Nix and devenv.

  1. Install Nix (recommended: Determinate Nix) and devenv.

  2. Optionally install direnv to activate the dev environment automatically when entering the directory (direnv allow). Without it, run devenv shell manually.

  3. Use the just recipes to build, test, and package:

    just          # list all available recipes
    just build    # build the codegen JAR and .NET solution
    just test     # run the test suite
    just fmt      # format all code
    just docs     # start the documentation dev server
    just ci       # run the full CI pipeline locally
    
  • Smithy: The IDL and protocol framework NSmithy is built on.
  • smithy4s: Scala codegen from Smithy models and the main inspiration for NSmithy.
  • alloy: Smithy extensions used by NSmithy for simpleRestJson and gRPC.
  • smithy-go / smithy-typescript: Official Smithy codegen plugins for Go and TypeScript.
  • TypeSpec: Microsoft's alternative API description language, with first-party .NET emitters.