Every developer who uses AI has felt this.
You open a new chat.
You explain your architecture.
You explain your file naming.
You explain that you do not use repositories, prefer a rich domain model, and that your handlers and services return a Result<T>.
The AI writes good code.
The next day, you open another chat, and you explain it all over again.
This is the hidden tax of AI-assisted development.
You repeat the same instructions in every session for every feature.
A CLAUDE.md file helps; it's added to every session, but you can't make it with a lot of instructions (it should be 100 lines or less).
It holds the facts about your project and overall architecture, not the step-by-step recipe for every kind of task you do.
There is a better way: skills.
A skill packages a set of instructions, and even example files, that Claude loads only when it needs them.
You write the recipe once, and Claude follows it every time, in every session.
Skills also work if you are using the OpenAI Codex agent
In this post, we will explore:
- What Claude skills are and why they beat repeating yourself
- The building blocks of a skill
- When a skill should trigger, and when it should not
- How to create a skill with the Skill Creator
- Where your skills live: Claude Code, Desktop, and CoWork
- How to encode your project's conventions as skills
- Skills for gRPC, GraphQL, messaging, and new services
- The ready-made .NET skills published by Microsoft
Let's dive in.
👉 Read original article on my newsletter: https://antondevtips.com/blog/creating-claude-skills-for-dotnet-apps
What Are Claude Skills (and Why They Beat Repeating Yourself)
A skill is a folder with instructions that Claude reads when a task matches.
it's placed in your repository root: .claude/skills/*
At its simplest, a skill is a single file called SKILL.md.
It has a short header that tells Claude what the skill does and when to use it, followed by the instructions themselves.
Here is a tiny skill:
---
name: create-endpoint
description: Create a new ASP.NET Core Minimal API endpoint following our project conventions.
Use whenever the user asks to add an endpoint, route, or API operation.
---
# Create a Minimal API Endpoint
1. Create the endpoint in `Features/<UseCase>/<UseCase>.Endpoint.cs`.
2. Implement `IApiEndpoint` and map the route from `RouteConsts`.
3. Call the handler, and convert a failed `Result<T>` with `ToProblem()`.
That is a complete, working skill.
When you ask Claude to "add an endpoint for canceling a shipment," it reads this skill and follows your steps, instead of inventing its own structure.
The difference between a skill and a one-off prompt is reuse.
A prompt lives and dies in a single chat session.
A skill is written once and then reused, shared, and version-controlled like any other file in your project.
This means every team member can use it.
Skills also keep your context small through progressive disclosure.
Claude always sees the skill's name and description, which is about one line of text.
It loads the full SKILL.md only when your task matches that description.
And it opens any bundled files only when it actually needs them.
This means you can have dozens of skills installed without flooding the model with text it does not need right now.
The skill remains quiet until it is useful.
Now that you know what a skill is, let's look at what goes inside one.
The Building Blocks of a Skill
Every skill is a folder. The only required file is SKILL.md.
Everything else is optional.
Here is the anatomy of a fuller skill:
create-feature/
├── SKILL.md (required: instructions + when to use)
├── references/ (optional: detailed docs loaded on demand)
│ └── architecture.md
├── scripts/ (optional: scripts Claude can run)
│ └── scaffold.ps1
└── assets/ (optional: files used in the output)
└── Endpoint.template.cs
The SKILL.md file has two parts.
The first part is the YAML frontmatter at the top, between the --- markers. Two fields matter most:
-
name- a short identifier in kebab-case, likecreate-feature. -
description- one or two sentences that tell Claude what the skill does and when to use it.
This is the most important line in the skill because it determines when the skill triggers. We will cover that in the next section.
The second part is the Markdown body. This is where you write the actual instructions: the steps, the rules, the examples, and the things to avoid.
The references/ folder holds detailed documents that Claude reads only when needed. Keep SKILL.md short and focused, and push long material - a full coding standard, an API reference, a list of edge cases - into separate files.
Claude opens them on demand, so your main instructions stay easy to follow.
The scripts/ folder holds code Claude can run instead of writing it from scratch.
A PowerShell or bash script that scaffolds a folder, or a small script that formats output, belongs here.
The assets/ folder holds files used in the result, like a project template, a Dockerfile, or a .cshtml view.
Note: Keep
SKILL.mdshort, ideally a few hundred lines at most. If it grows large, that is a signal to move the details intoreferences/and point to them from the body. A focused skill is easier for Claude to follow than one giant wall of rules.
A skill is only useful if Claude opens it at the right moment. Let's look at what controls that.
👉 Read original article on my newsletter: https://antondevtips.com/blog/creating-claude-skills-for-dotnet-apps
Top comments (1)
The description has a hard edge in Claude Code: description plus when_to_use is cut at 1,536 characters in the skill listing, so the trigger phrases should come first. And for a skill you don't want firing on its own, like a deploy, disable-model-invocation: true means it only runs when someone types /deploy.