Agent skill

.NET API Compatibility Design

by Aaronontheweb in Aaronontheweb/dotnet-skills

Applies extend-only design rules to NuGet packages and distributed systems, covering source, binary and wire compatibility and how to deprecate members safely.

MITAuto-check passedBackend & APIs

Install .NET API Compatibility Design

skills CLI
$ npx skills add Aaronontheweb/dotnet-skills --skill api-design -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install Aaronontheweb/dotnet-skills api-design --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/Aaronontheweb/dotnet-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/csharp-api-design .claude/skills/api-design && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
api-design
GitHub stars
1.2k
Used in
2 other repos
Token cost
~2.7k tokens
SKILL.md length
587 words
Files
1
Skills in repo
33
Repo updated
First seen
Licence
MIT

At a glance

Applies extend-only design rules to NuGet packages and distributed systems, covering source, binary and wire compatibility and how to deprecate members safely.

  • Works in 3 steps: Previous functionality is immutable -… → New functionality through new constructs… → Removal only after deprecation period -…
  • Designing a new public API for a NuGet package that must stay compatible across versions
  • SKILL.md covers When to Use This Skill, The Three Types of Compatibility, Extend-Only Design and API Change Guidelines, plus 6 more sections
  • Calls dotnet

What it does

The skill distinguishes three kinds of compatibility a public API change can break: source or API compatibility, meaning code still compiles against the newer version; binary compatibility, meaning compiled code still runs against it without recompiling; and wire compatibility, meaning serialized data stays readable across versions on the network or in storage. Its core rule is extend-only design, resting on three pillars: previously released behavior and signatures are immutable, new functionality arrives through new constructs such as overloads or opt-in types rather than changes to existing ones, and removal happens only after a deprecation period measured in years, not releases.

Concrete C# examples separate safe changes, such as adding a new overload that delegates to an existing method, from unsafe ones, such as removing or renaming a public member, which are reserved for a major version if ever done at all. A deprecation pattern shows marking a member Obsolete with the version and replacement noted, which can happen in any release. To catch accidental breaking changes automatically, the skill sets up API approval testing with the PublicApiGenerator and Verify.Xunit NuGet packages, generating a verified text file of the public surface that a test compares against on every run.

When your agent uses it

  • Designing a new public API for a NuGet package that must stay compatible across versions
  • Deciding whether a proposed code change is safe or a breaking change
  • Setting up automated API approval tests to catch breaking changes
  • Deprecating a public member without breaking existing consumers

Example prompts

  • “Is removing this parameter from a public method a breaking change for consumers?”
  • “Add a new overload to this method instead of changing its signature.”
  • “Set up API approval testing with PublicApiGenerator and Verify.Xunit for this project.”
  • “Deprecate this method and point callers to ProcessAsync instead.”

Requirements

  • .NET with the PublicApiGenerator and Verify.Xunit NuGet packages for approval testing

Workflow steps

3 steps, taken from the first numbered list in SKILL.md.

  1. Previous functionality is immutable - Once released, behavior and signatures are locked
  2. New functionality through new constructs - Add overloads, new types, opt-in features
  3. Removal only after deprecation period - Years, not releases

What it can do on your machine

Read from SKILL.md and the folder at commit e426ed9. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • dotnet

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • aaronstannard.com
    • getakka.net
    • semver.org
    • github.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

.NET API Compatibility Design loads about 2.7k tokens when it runs. Until then it costs about 48 tokens; SKILL.md has 587 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~48
When it runs · the whole SKILL.md, loaded when a task matches
~2.7k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from Aaronontheweb/dotnet-skills at commit e426ed9, republished under its MIT licence (© Aaronontheweb). 587 words, ~2,699 tokens.

Download SKILL.mdSave it as .claude/skills/api-design/SKILL.md (or your agent's skills folder).
name
api-design
description
Design stable, compatible public APIs using extend-only design principles. Manage API compatibility, wire compatibility, and versioning for NuGet packages and distributed systems.
invocable
false

Public API Design and Compatibility

When to Use This Skill

Use this skill when:

  • Designing public APIs for NuGet packages or libraries
  • Making changes to existing public APIs
  • Planning wire format changes for distributed systems
  • Implementing versioning strategies
  • Reviewing pull requests for breaking changes

The Three Types of Compatibility

TypeDefinitionScope
API/SourceCode compiles against newer versionPublic method signatures, types
BinaryCompiled code runs against newer versionAssembly layout, method tokens
WireSerialized data readable by other versionsNetwork protocols, persistence formats

Breaking any of these creates upgrade friction for users.


Extend-Only Design

The foundation of stable APIs: never remove or modify, only extend.

Three Pillars
  1. Previous functionality is immutable - Once released, behavior and signatures are locked
  2. New functionality through new constructs - Add overloads, new types, opt-in features
  3. Removal only after deprecation period - Years, not releases
Benefits
  • Old code continues working in new versions
  • New and old pathways coexist
  • Upgrades are non-breaking by default
  • Users upgrade on their schedule

Resources:


API Change Guidelines

Safe Changes (Any Release)
csharp
// SAFE: Add NEW overload methods that delegate to existing methods
// Existing method - do not modify its signature
public void Process(Order order) { ... }
// New overload - safe to add
public void Process(Order order, CancellationToken ct)
{
    // implementation that handles cancellation
}

// SAFE: Add NEW overloads for additional functionality
// Existing method - do not modify
public void Send(Message msg) { ... }
// New overload - safe to add
public void Send(Message msg, Priority priority)
{
    // implementation that handles priority
}

// ADD new types, interfaces, enums
public interface IOrderValidator { }
public enum OrderStatus { Pending, Complete, Cancelled }

// ADD new members to existing types
public class Order
{
    public DateTimeOffset? ShippedAt { get; init; }  // NEW
}
Unsafe Changes (Never or Major Version Only)
csharp
// REMOVE or RENAME public members
public void ProcessOrder(Order order);  // Was: Process()

// CHANGE parameter types or order
public void Process(int orderId);  // Was: Process(Order order)

// CHANGE return types
public Order? GetOrder(string id);  // Was: public Order GetOrder()

// CHANGE access modifiers
internal class OrderProcessor { }  // Was: public

// ADD optional parameters to EXISTING methods (binary incompatible!)
// The compiled IL method signature changes - callers compiled against
// the old signature will get MissingMethodException at runtime.
// Optional parameter defaults are baked into the CALLER's assembly at compile time.
public void Process(Order order, CancellationToken ct = default);  // Breaks binary compat!
public void Send(Message msg, Priority priority = Priority.Normal);  // Breaks binary compat!
// Correct approach: add a NEW overload method instead (see Safe Changes above)

// ADD required parameters without defaults
public void Process(Order order, ILogger logger);  // Breaks callers!
Deprecation Pattern
csharp
// Step 1: Mark as obsolete with version (any release)
[Obsolete("Obsolete since v1.5.0. Use ProcessAsync instead.")]
public void Process(Order order) { }

// Step 2: Add new recommended API (same release)
public Task ProcessAsync(Order order, CancellationToken ct = default);

// Step 3: Remove in next major version (v2.0+)
// Only after users have had time to migrate

API Approval Testing

Prevent accidental breaking changes with automated API surface testing.

Using ApiApprover + Verify
bash
dotnet add package PublicApiGenerator
dotnet add package Verify.Xunit
csharp
[Fact]
public Task ApprovePublicApi()
{
    var api = typeof(MyLibrary.PublicClass).Assembly.GeneratePublicApi();
    return Verify(api);
}

Creates ApprovePublicApi.verified.txt:

csharp
namespace MyLibrary
{
    public class OrderProcessor
    {
        public OrderProcessor() { }
        public void Process(Order order) { }
        public Task ProcessAsync(Order order, CancellationToken ct = default) { }
    }
}

Any API change fails the test - reviewer must explicitly approve changes.

PR Review Process
  1. PR includes changes to *.verified.txt files
  2. Reviewers see exact API surface changes in diff
  3. Breaking changes are immediately visible
  4. Conscious decision required to approve

Wire Compatibility

For distributed systems, serialized data must be readable across versions.

Requirements
DirectionRequirement
BackwardOld writers → New readers (current version reads old data)
ForwardNew writers → Old readers (old version reads new data)

Both are required for zero-downtime rolling upgrades.

Safely Evolving Wire Formats

Phase 1: Add read-side support (opt-in)

csharp
// New message type - readers deployed first
public sealed record HeartbeatV2(
    Address From,
    long SequenceNr,
    long CreationTimeMs);  // NEW field

// Deserializer handles both old and new
public object Deserialize(byte[] data, string manifest) => manifest switch
{
    "Heartbeat" => DeserializeHeartbeatV1(data),   // Old format
    "HeartbeatV2" => DeserializeHeartbeatV2(data), // New format
    _ => throw new NotSupportedException()
};

Phase 2: Enable write-side (opt-out, next minor version)

csharp
// Config to enable new format (off by default initially)
akka.cluster.use-heartbeat-v2 = on

Phase 3: Make default (future version)

After install base has absorbed read-side code.

Schema-Based Serialization

Prefer schema-based formats over reflection-based:

FormatTypeWire Compatibility
Protocol BuffersSchema-basedExcellent - explicit field numbers
MessagePackSchema-basedGood - with contracts
System.Text.JsonSchema-based (with source gen)Good - explicit properties
Newtonsoft.JsonReflection-basedPoor - type names in payload
BinaryFormatterReflection-basedTerrible - never use

See dotnet/serialization skill for details.


Show full SKILL.md (221 more words)Show less

Encapsulation Patterns

Internal APIs

Mark non-public APIs explicitly:

csharp
// Attribute for documentation
[InternalApi]
public class ActorSystemImpl { }

// Namespace convention
namespace MyLibrary.Internal
{
    public class InternalHelper { }  // Public for extensibility, not for users
}

Document clearly:

Types in .Internal namespaces or marked with [InternalApi] may change between any releases without notice.

Sealing Classes
csharp
// DO: Seal classes not designed for inheritance
public sealed class OrderProcessor { }

// DON'T: Leave unsealed by accident
public class OrderProcessor { }  // Users might inherit, blocking changes
Interface Segregation
csharp
// DO: Small, focused interfaces
public interface IOrderReader
{
    Order? GetById(OrderId id);
}

public interface IOrderWriter
{
    Task SaveAsync(Order order);
}

// DON'T: Monolithic interfaces (can't add methods without breaking)
public interface IOrderRepository
{
    Order? GetById(OrderId id);
    Task SaveAsync(Order order);
    // Adding new methods breaks all implementations!
}

Versioning Strategy

Semantic Versioning (Practical)
VersionChanges Allowed
Patch (1.0.x)Bug fixes, security patches
Minor (1.x.0)New features, deprecations, obsolete removal
Major (x.0.0)Breaking changes, old API removal
Key Principles
  1. No surprise breaks - Even major versions should be announced and planned
  2. Extensions anytime - New APIs can ship in any release
  3. Deprecate before remove - [Obsolete] for at least one minor version
  4. Communicate timelines - Users need to plan upgrades
Chesterton's Fence

Before removing or changing something, understand why it exists.

Assume every public API is used by someone. If you want to change it:

  1. Socialize the proposal on GitHub
  2. Document migration path
  3. Provide deprecation period
  4. Ship in planned release

Pull Request Checklist

When reviewing PRs that touch public APIs:

  • No removed public members (use [Obsolete] instead)
  • No changed signatures (add overloads instead)
  • No new required parameters (use defaults)
  • API approval test updated (.verified.txt changes reviewed)
  • Wire format changes are opt-in (read-side first)
  • Breaking changes documented (release notes, migration guide)

Anti-Patterns

Breaking Changes Disguised as Fixes
csharp
// "Bug fix" that breaks users
public async Task<Order> GetOrderAsync(OrderId id)  // Was sync!
{
    // "Fixed" to be async - but breaks all callers
}

// Correct: Add new method, deprecate old
[Obsolete("Use GetOrderAsync instead")]
public Order GetOrder(OrderId id) => GetOrderAsync(id).Result;

public async Task<Order> GetOrderAsync(OrderId id) { }
Silent Behavior Changes
csharp
// Changing defaults breaks users who relied on old behavior
public void Configure(bool enableCaching = true)  // Was: false!

// Correct: New parameter with new name
public void Configure(
    bool enableCaching = false,  // Original default preserved
    bool enableNewCaching = true)  // New behavior opt-in
Polymorphic Serialization
csharp
// AVOID: Type names in wire format
{ "$type": "MyApp.Order, MyApp", "Id": 123 }

// Renaming Order class = wire break!

// PREFER: Explicit discriminators
{ "type": "order", "id": 123 }

Resources

© Aaronontheweb, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in skills/csharp-api-design of Aaronontheweb/dotnet-skills.

Open the folder on GitHubat commit e426ed9

Used in 2 other repositories

We found 3 copies of this SKILL.md (exact, near-identical or edited) in other folders, from 2 other GitHub owners. This page covers the copy in Aaronontheweb/dotnet-skills, which our catalogue first saw on October 7, 2026.

Compare with similar skills

.NET API Compatibility Design next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

.NET API Compatibility Design compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
.NET API Compatibility Design this skillAaronontheweb/dotnet-skills1.2k2 repos~2.7kAutomated safety check: PassMIT
Generate Testability Wrappersdotnet/skills5.6k1 repos~3.9kAutomated safety check: PassMIT
Generate Testability Wrappersmicrosoft/testfx1k—~2.2kAutomated safety check: PassMIT
Csharp Dotnetericrisco/rsc-harness156—~3.3kAutomated safety check: PassMIT
Tsp Csharpquerylenshq/ef-querylens225—~1.3kAutomated safety check: PassMIT
DisCatSharp Discord DevelopmentAiko-IT-Systems/DisCatSharp140—~1.2kAutomated safety check: PassMIT

Similar skills

  • Official

    DO NOT USE when the target already consumes an injected interface or built-in abstraction such as IFileSystem or TimeProvider, even if the request says "generate a wrapper"; no new wrapper is needed.

    5.6k GitHub starsUsed in 1 repo~3.9k tokens
    Backend & APIsAuto-check passed
  • Official

    Generate wrapper interfaces and DI registration for hard-to-test static dependencies in C.

    1k GitHub stars~2.2k tokensUpdated today
    Backend & APIsAuto-check passed
  • Csharp Dotnet

    ericrisco/rsc-harness

    A skill your agent uses when writing, reviewing, testing, or shipping C / .NET code — ASP.NET Core APIs (minimal APIs vs controllers), EF Core data access, async correctness, solution layout in…

    156 GitHub stars~3.3k tokensUpdated today
    Backend & APIsAuto-check passed
  • Tsp Csharp

    querylenshq/ef-querylens

    Comprehensive C and .NET development skill for TSP projects.

    225 GitHub stars~1.3k tokensUpdated 1 mo ago
    Backend & APIsAuto-check passed
  • DisCatSharp Discord Development

    Aiko-IT-Systems/DisCatSharp

    Helps build, explain and troubleshoot C# Discord apps on DisCatSharp, answering from the project's installed version and the library's documentation rather than guesses.

    140 GitHub stars~1.2k tokensUpdated yesterday
    Backend & APIsAuto-check passed
  • Master C/.NET backend development patterns for building robust APIs, MCP servers, and enterprise applications.

    40k GitHub starsUsed in 7 repos~6.6k tokens
    Backend & APIsAuto-check passed

More from Aaronontheweb/dotnet-skills

All 33 skills in this repo
  • .NET Trimming and Native AOT

    Aaronontheweb/dotnet-skills

    Guides making .NET libraries trimming-safe and Native-AOT compatible: the MSBuild properties, trimming attributes, warning codes and a playbook of safe patterns.

    1.2k GitHub stars~2.9k tokensUpdated 19 days ago
    Auto-check passed
  • Akka.Hosting Actor Patterns

    Aaronontheweb/dotnet-skills

    Shows how to build entity actors with Akka.Hosting so the same code runs in local unit tests and in a sharded cluster in production.

    1.2k GitHub starsUsed in 1 repo~5k tokens
    Auto-check passed
  • Akka.NET Best Practices

    Aaronontheweb/dotnet-skills

    Guidance for Akka.NET actor systems covering EventStream versus DistributedPubSub, supervision, Props versus DependencyResolver, work distribution and testable cluster code.

    1.2k GitHub starsUsed in 1 repo~3.3k tokens
    Auto-check passed
  • Akka.NET Management and Discovery

    Aaronontheweb/dotnet-skills

    Sets up Akka.Management and Cluster.Bootstrap so Akka.NET clusters form through service discovery on Kubernetes, Azure or config instead of static seed nodes.

    1.2k GitHub starsUsed in 1 repo~2.5k tokens
    Auto-check passed
  • Akka.NET Testing Patterns

    Aaronontheweb/dotnet-skills

    Shows how to test Akka.NET actors with Akka.Hosting.TestKit: swapping services for fakes, using TestProbes, and checking persistence, plus when the older TestKit still fits.

    1.2k GitHub starsUsed in 1 repo~2.4k tokens
    Auto-check passed
  • .NET Aspire Explicit Configuration

    Aaronontheweb/dotnet-skills

    Wires .NET Aspire AppHost resources into explicit environment-variable configuration, keeping application code free of Aspire client packages and service discovery.

    1.2k GitHub starsUsed in 1 repo~1.3k tokens
    Auto-check passed

Works with

Questions about .NET API Compatibility Design

What does .NET API Compatibility Design do?

Applies extend-only design rules to NuGet packages and distributed systems, covering source, binary and wire compatibility and how to deprecate members safely. The skill distinguishes three kinds of compatibility a public API change can break: source or API compatibility, meaning code still compiles against the newer version; binary compatibility, meaning compiled code still runs against it without recompiling; and wire compatibility, meaning serialized data stays readable across versions on the network or in storage. Its core rule is extend-only design, resting on three pillars: previously released behavior and signatures are immutable, new functionality arrives through new constructs such as overloads or opt-in types rather than changes to existing ones, and removal happens only after a deprecation period measured in years, not releases.

When should I use .NET API Compatibility Design?

.NET API Compatibility Design fits situations like: designing a new public API for a NuGet package that must stay compatible across versions; deciding whether a proposed code change is safe or a breaking change; setting up automated API approval tests to catch breaking changes; deprecating a public member without breaking existing consumers.

How do I install .NET API Compatibility Design in Claude Code?

Run `npx skills add Aaronontheweb/dotnet-skills --skill api-design -a claude-code`. Or copy the skill folder (skills/csharp-api-design in Aaronontheweb/dotnet-skills) into .claude/skills/api-design in your project. Claude Code loads it when a task matches its description.

How do I install .NET API Compatibility Design in Codex?

Run `npx skills add Aaronontheweb/dotnet-skills --skill api-design -a codex`. Or copy the skill folder (skills/csharp-api-design in Aaronontheweb/dotnet-skills) into .agents/skills/api-design in your project. Codex loads it when a task matches its description.

Can I use .NET API Compatibility Design in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add Aaronontheweb/dotnet-skills --skill api-design -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/api-design, .gemini/skills/api-design, .github/skills/api-design and .opencode/skills/api-design in your project.

What does .NET API Compatibility Design need to run?

Going by SKILL.md and its folder, .NET API Compatibility Design needs the command-line tools its instructions call (dotnet). Our summary lists: .NET with the PublicApiGenerator and Verify.Xunit NuGet packages for approval testing.

Does .NET API Compatibility Design access the network?

SKILL.md names 4 domains. As links in the text: aaronstannard.com, getakka.net, semver.org and github.com. This is read from the text; nothing was executed.

Is .NET API Compatibility Design safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does .NET API Compatibility Design use?

.NET API Compatibility Design is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does .NET API Compatibility Design use?

About 2.7k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to .NET API Compatibility Design?

Skills that share tags, products or a category with .NET API Compatibility Design: Generate Testability Wrappers (dotnet/skills, 5.6k stars), Generate Testability Wrappers (microsoft/testfx, 1k stars), Csharp Dotnet (ericrisco/rsc-harness, 156 stars) and Tsp Csharp (querylenshq/ef-querylens, 225 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains .NET API Compatibility Design?

Aaronontheweb (a GitHub user) maintains it in Aaronontheweb/dotnet-skills, which has 1,202 GitHub stars. The repository holds 33 skills in this directory. The repository was last updated on September 17, 2026.

Source: Aaronontheweb/dotnet-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.