Rivet.Attributes 0.39.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Rivet.Attributes --version 0.39.0
                    
NuGet\Install-Package Rivet.Attributes -Version 0.39.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="Rivet.Attributes" Version="0.39.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Rivet.Attributes" Version="0.39.0" />
                    
Directory.Packages.props
<PackageReference Include="Rivet.Attributes" />
                    
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 Rivet.Attributes --version 0.39.0
                    
#r "nuget: Rivet.Attributes, 0.39.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 Rivet.Attributes@0.39.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=Rivet.Attributes&version=0.39.0
                    
Install as a Cake Addin
#tool nuget:?package=Rivet.Attributes&version=0.39.0
                    
Install as a Cake Tool

<p align="center"> <h1 align="center">Rivet</h1> <p align="center"> <a href="https://www.nuget.org/packages/Rivet.Attributes"><img src="https://img.shields.io/nuget/v/Rivet.Attributes?label=Rivet.Attributes" alt="NuGet" /></a> <a href="https://www.nuget.org/packages/dotnet-rivet"><img src="https://img.shields.io/nuget/v/dotnet-rivet?label=dotnet-rivet" alt="NuGet" /></a> <img src="https://img.shields.io/badge/license-MIT-blue" alt="License" /> </p> </p>

Your C# is the contract. Rivet reads your compiled C# with Roslyn and emits an OpenAPI 3.1 spec — no runtime reflection, no attributes-on-everything, no drift between the code and the spec. The OpenAPI ecosystem does the rest: TypeScript types, a typed fetch client, Zod schemas, rendered docs.

oRPC gives you this when your server is TypeScript. Rivet gives you the same DX when your server is .NET.

dotnet add package Rivet.Attributes
dotnet tool install --global dotnet-rivet

Two ways in

Already have an ASP.NET API? Annotate it.

Mark the endpoints you want surfaced — the operation is derived from the real transport shape (routes, params, bodies, response types):

[ApiController]
[Route("api/tasks")]
public sealed class TasksController : ControllerBase
{
    [RivetEndpoint]
    [HttpGet("{id:guid}")]
    [ProducesResponseType(typeof(TaskDetailDto), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(NotFoundDto), StatusCodes.Status404NotFound)]
    public async Task<IActionResult> Get(Guid id, CancellationToken ct) { ... }
}

That becomes GET /api/tasks/{id} with a typed 200 and 404 — route constraints normalised, params classified, multipart and form bodies handled.

Starting fresh? Write the contract first.

A contract is plain C#: routes, inputs, outputs, and error responses in one place, as data:

[RivetContract]
public static class MembersContract
{
    public static readonly RouteDefinition<PagedResult<MemberDto>> List =
        Define.Get<PagedResult<MemberDto>>("/api/members");

    public static readonly RouteDefinition<InviteMemberRequest, InviteMemberResponse> Invite =
        Define.Post<InviteMemberRequest, InviteMemberResponse>("/api/members")
            .Status(201)
            .Returns<ValidationErrorDto>(422, "Validation failed")
            .Secure("admin");
}

Handlers execute the contract, so the compiler enforces that your implementation matches the declaration — input type, output type, and (at runtime, on the typed-results path) status codes:

[HttpPost]
public async Task<IActionResult> Invite([FromBody] InviteMemberRequest request, CancellationToken ct)
    => (await MembersContract.Invite.Invoke(request, async req =>
    {
        // req is InviteMemberRequest; must return InviteMemberResponse — compiler-enforced
        return new InviteMemberResponse(Guid.NewGuid());
    })).ToActionResult();

Either way — annotated endpoints, contracts, or a mix — the spec comes out the same.

Generate

dotnet rivet --project path/to/Api.csproj --output ./generated

Writes ./generated/openapi.json, derived from the compiled C# via the Roslyn semantic model. Value-object brands, generics, nullability, validation attributes, polymorphic hierarchies (oneOf + discriminator), dictionary key types, headers, descriptions, and examples all flow into the spec.

Consume

The spec plugs straight into the OpenAPI TypeScript ecosystem:

npx openapi-typescript ./generated/openapi.json -o ./src/api/schema.d.ts
npm install openapi-fetch
import createClient from "openapi-fetch";
import type { paths } from "./api/schema";

const api = createClient<paths>({ baseUrl: "https://api.example.com" });

// Path, params, body, and per-status responses all inferred.
const { data, error } = await api.GET("/api/tasks/{id}", {
  params: { path: { id: taskId } },
});

if (error) {
  // narrowed to NotFoundDto for the declared 404
  console.error(error.message);
}

Docs via any OpenAPI renderer; runtime validators via openapi-zod-client if you want them.

Also in the box

  • Contract coverage checking — --check verifies every contract field has an implementation on the declared route and method
  • OpenAPI import — one-shot onboarding for existing APIs: generate C# contracts from a spec, then the C# is the source of truth
  • File endpoints, headers as contract concepts, minimal-API hosts, round-trippable specs
  • Stable RIVnnnn diagnostic IDs on every warning — grep or baseline by ID
  • A TypeScript-first sibling, rivet-ts — same pipeline, contracts authored as TS types, Hono runtime

Documentation

Getting Started · Contracts · CLI Reference · Type Mapping · Runtime Validation (the precise scope of what is and isn't enforced at runtime)

License

MIT

Product Compatible and additional computed target framework versions.
.NET 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 is compatible.  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 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.
  • net9.0

    • 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.46.0 255 10/3/2026
0.45.1 86 9/30/2026
0.45.0 115 9/29/2026
0.44.1 100 9/21/2026
0.44.0 95 9/19/2026
0.43.0 106 9/18/2026
0.42.0 95 9/17/2026
0.41.0 521 7/13/2026
0.40.0 140 7/11/2026
0.39.0 125 7/11/2026
0.38.0 123 6/13/2026
0.37.0 130 6/12/2026
0.36.1 126 6/12/2026
0.36.0 118 6/12/2026
0.35.0 117 6/12/2026
0.34.3 140 5/22/2026
0.34.2 122 5/11/2026
0.34.1 113 5/11/2026
0.34.0 116 4/21/2026
0.33.2 126 4/16/2026
Loading failed