Preview Docs
1.0.0-alpha ยท Preview
๐Ÿค– Agent-Ready

Pragmatic Design
for .NET

The Foundry of Precision Code

One generator to rule them all, one generator to find them,
one generator to bring them all โ€” and at compile time bind them.

Describe your domain. One source generator writes the application around it โ€” plain C# you can read, checked at compile time, and yours.

ConfirmReservationMutation.cs You write
[Endpoint(HttpVerb.Post, "/{id}/confirm")]
[EndpointGroup<ReservationsGroup>]
[RequirePermission(BookingPermissions.Reservation.Update)]
[Mutation(Mode = MutationMode.Update)]
[TransitionsTo<ReservationStatus>(ReservationStatus.Confirmed)]
public partial class ConfirmReservationMutation
    : Mutation<Reservation, ConflictError>
{
    public required Guid Id { get; init; }
}

// No body: load, permission, transition, commit
// and the 409 are all declared.
ConfirmReservationMutation.Endpoint.g.cs Generated
// excerpt โ€” ordinary C#, in obj/
var builder = endpoints.MapPost("/{id}/confirm", ...
{
    if (!RequestBinder.TryBind<Guid>(__raw_id, out var id))
    { /* 400, naming the field */ }
    var invoker = services.GetRequiredService<
        IMutationInvoker<ConfirmReservationMutation, Reservation>>();
    // โ€ฆ
});
builder.RequireAuthorization(policy => policy.AddRequirements(
    new PragmaticPermissionRequirement(
        new[] { "booking.reservation.update" }, PermissionMode.All)));
builder.WithMetadata(new ProducesResponseTypeMetadata(409, ...));
// โ€ฆ 200, 400, 401, 403, 404, 422 and 500 likewise

Declare Intent.
The Compiler Writes the Plumbing.

What the generator can decide at compile time, it decides there, and emits the line that does it โ€” not a lookup that might find nothing at runtime.

โšก

One Generator

One incremental source generator, 31 feature pipelines: repositories, endpoints, validators, invokers, DI wiring, OpenAPI โ€” from the declarations you write.

๐Ÿงฉ

Modular by Design

45 modules. Reference a package and its feature switches on; remove it and the code it generated disappears. Adopt one library or the whole stack.

๐Ÿ”’

Mistakes Are Diagnostics

Over 400 PRAG diagnostics, each with an ID and a location, catch at build time what would otherwise fail on the first request โ€” or in production.

๐Ÿค–

Built for Agents Too

A declaration is a dozen typed lines an agent can read; a diagnostic is a loop it can close on its own. A Claude Code plugin with 35 skills teaches the framework.

๐Ÿš€

AOT-First Design

The generated code never reflects, and a web host serving generated endpoints is published Native AOT by the gate. EF Core is not AOT-compatible yet, so a host with persistence is not an AOT application today.

๐Ÿ“

The Module Declares, the Host Composes

Each module states facts about itself; the host, which sees every assembly, puts them together โ€” the same modules run as one host or as two.

The Shift.
Verbosity Becomes Advantage.

For decades, C# developers fought verbosity with abstractions, magic strings, and reflection. Source generators change the equation.

The Old Approach

You write explicit, descriptive code โ€” but then you pay the price at runtime. The framework uses reflection to discover your types, scan assemblies, build registrations. Startup is slow, trimming breaks, and a missing registration is found by the first request.

  • โœ— Reflection-based discovery at startup
  • โœ— Convention-over-configuration hides intent
  • โœ— Runtime errors for compile-time mistakes
  • โœ— Hand-written plumbing, a little different every time

The Pragmatic Approach

You write the same explicit, descriptive code โ€” but now the compiler reads it before the runtime does. Attributes and types become instructions for the source generator. Verbosity is no longer a cost. It's the input.

  • โœ“ Compile-time code generation โ€” no runtime discovery
  • โœ“ Explicit declarations are the input, not the cost
  • โœ“ Build errors for declarations that do not fit together
  • โœ“ Plumbing written the same way every time, tested once

"The best code is not the shortest โ€” it's the most legible to both humans and machines. A source generator lets you be as descriptive as you want, at no runtime cost."

Your code speaks.
Agents read it.

A declarative API is semantic by construction. Attributes like [DomainAction], [Mutation(Mode = MutationMode.Create)] and [Query<T, TDto>] carry meaning โ€” not just configuration.

Repetitive code is where agents are weakest: every copy is a little different, and every copy is code to review. A generator writes it the same way every time. What is left to review is the declaration and the domain logic โ€” a few dozen lines, not a few hundred.

  • โ†’ The context is small โ€” a declaration is a dozen typed lines
  • โ†’ The feedback is immediate โ€” a diagnostic at build time, with a location
  • โ†’ Patterns are consistent โ€” one way to do each thing
SearchReservationsQuery.cs
// A read with no body: filters, sorting and a
// projection computed in SQL.

[Query<Reservation, ReservationSummaryDto>]
[RequirePermission(BookingPermissions.Reservation.Read)]
[Endpoint(HttpVerb.Get, "api/reservations/search")]
public partial class SearchReservationsQuery
{
    [Filter] public Guid? GuestId { get; init; }
    [Filter] public ReservationStatus? Status { get; init; }

    [Sort(DefaultDirection = SortDirection.Descending)]
    public SortDirection? CheckInSort { get; init; }
}

Built for the
AI-Assisted Developer.

You still read what the agent wrote. There is just much less of it, and none of it is plumbing.

๐Ÿ“–

Docs for People and Agents

Every module documents its concepts, common mistakes and troubleshooting, and an llms.txt indexes it all for an agent.

339 pages ยท 44 modules
๐Ÿ› ๏ธ

Claude Code Skills

A plugin that teaches the framework: pragmatic-new-app interviews you about your domain and scaffolds the solution; pragmatic-use-persistence, pragmatic-use-actions-endpoints and the others know each module, with examples copied from tested code.

35 skills
๐Ÿง 

A Loop the Agent Closes

When two declarations do not fit together, the build says so, with an ID and a location โ€” feedback an agent can act on before a person looks at anything.

400+ diagnostics

AOT-First. Not Full-Stack Yet.

The code Pragmatic generates never reflects: serialization goes through generated JsonTypeInfo, and endpoints are mapped as plain request delegates rather than through ASP.NET's runtime delegate factory. Three smoke applications โ€” a web host serving a generated endpoint among them โ€” are published Native AOT and run by the gate.

What is not AOT yet. Entity Framework Core is not fully compatible with trimming and AOT, so a host with persistence is not a Native AOT application today. The generated HTTP client has no JSON context yet. And some runtime code is not trim-safe โ€” reflective fallbacks, configuration binding: it is annotated, and the gate counts it, with a budget that can only go down.

Generated serialization โ€” proven under AOT Generated endpoints โ€” proven under AOT Generated client โ€” not yet Persistence โ€” not AOT (EF Core)

What's Forged.
What's Next.

The first public release is 1.0.0-alpha: a core set of modules is stable, the others are functional or in preview, and APIs can still change before 1.0.

In 1.0.0-alpha

45 Modules, One Generator

Entities, repositories and declarative queries; mutations and domain actions with a generated pipeline; minimal-API endpoints with OpenAPI; identity, roles, permissions and multi-tenancy โ€” composed by one source generator.

In 1.0.0-alpha

Messaging, Sagas, Jobs

A transactional outbox; transports over Channels, RabbitMQ, Kafka, Azure Service Bus or SQL; sagas with compensation; background jobs with retry, timeout and distributed locking.

In 1.0.0-alpha

Compliance

GDPR erasure, retention, consent, access and portability; an append-only audit trail that can be verified; NIS2 incident reporting clocks; personal-data redaction in logs and audit; encryption at rest with key rotation.

In 1.0.0-alpha

Reference Applications

The Showcase and four applications โ€” Time off, Invoicing, Casework, Warehouse โ€” each tested end to end against real databases and brokers, plus runnable samples for every module.

In 1.0.0-alpha

Entity Traits

[HasComments], [HasTags], [HasAttachments] and [HasNotes]: one attribute on an entity brings its child entity, actions and endpoints.

In 1.0.0-alpha

Documents & Media

PDF, DOCX, XLSX, CSV and e-mail from templates, in the recipient's language; native (Rust) image resizing, conversion and QR codes; file storage on disk and in the cloud.

Next

Packages on nuget.org

Today the alpha builds are consumed from a local feed. Publishing them is the next step.

Before 1.0

Settle the Functional Modules

The modules still marked functional or preview fix their names and shapes and become stable. Each module's README says where it stands.

Forging in Progress

Pragmatic Design is in public alpha. Explore the documentation to see what's already built.

Explore Documentation