Kipt

Your prompts and skills, one keystroke away.

Explore

CLAUDE.md for .NET: a copyable template for ASP.NET Core and C# projects

A CLAUDE.md for .NET you can copy: dotnet build, test, format and ef commands, solution layout, nullable and secrets rules, EF Core migrations, plus AGENTS.md.

By the Kipt team · Updated 26 October 2026

What should a CLAUDE.md for .NET include?

A CLAUDE.md for .NET should give Claude Code the dotnet commands to build, run, test, format and migrate, map the projects in your solution, and state your rules for nullable reference types, configuration, secrets, async code and EF Core migrations. Keep it under 200 lines, as Anthropic's memory docs recommend, and add the gotchas that live only in your team's heads.

.NET solutions are hard for an agent to read cold. One solution can hold an API project, a domain library, an infrastructure project and several test projects, and the EF Core commands need to know which project holds the migrations and which one starts the app. Claude can work that out, but it costs a few failed commands every session. Writing it once in CLAUDE.md saves those turns.

The template targets an ASP.NET Core Web API on .NET 10, which the .NET support policy lists as the current long-term support release, with EF Core and xUnit. The Api, Core and Infrastructure project split is a common layout, not a requirement, so rename or collapse it to match your solution. For the file format itself, see what a CLAUDE.md file is.

The .NET CLAUDE.md template

Save this as CLAUDE.md next to your solution file, replace the angle-bracket placeholders, and delete lines that do not apply.

# <App name>

<One sentence: what this service does and who calls it.>
Stack: .NET 10 (SDK pinned in global.json), ASP.NET Core minimal APIs, EF Core,
<PostgreSQL>, xUnit. Solution: <App>.slnx

## Commands
- Build: `dotnet build`
- Run the API: `dotnet run --project src/<App>.Api`
- Run with hot reload: `dotnet watch --project src/<App>.Api`
- All tests: `dotnet test`
- Tests by name: `dotnet test --filter FullyQualifiedName~OrderServiceTests`
- Format: `dotnet format`. Check only: `dotnet format --verify-no-changes`
- New migration: `dotnet ef migrations add <Name> --project src/<App>.Infrastructure --startup-project src/<App>.Api`
- Apply locally: `dotnet ef database update --project src/<App>.Infrastructure --startup-project src/<App>.Api`
- Undo the last migration (not yet applied anywhere shared): `dotnet ef migrations remove` with the same flags
- Done means: build with no new warnings, format check and tests all pass

## Solution structure
- `src/<App>.Api/`: Program.cs, endpoints, request and response records
- `src/<App>.Core/`: domain types and services. No reference to EF Core or ASP.NET Core
- `src/<App>.Infrastructure/`: DbContext, migrations, external clients
- `tests/<App>.Tests/`: unit tests. `tests/<App>.IntegrationTests/`: API tests
- `Directory.Build.props`: shared MSBuild settings. `.editorconfig`: style rules
- `global.json`: SDK version and test runner

## C# rules
- Nullable reference types are on. Fix warnings; no `!` without a comment saying why
- Async all the way: no `.Result` or `.Wait()`. Pass `CancellationToken` through
- Dependencies come through constructors and DI registration in Program.cs
- Settings bind to options classes (`IOptions<T>`), not raw `IConfiguration` lookups
- Endpoints return request and response records, never EF entities
- File-scoped namespaces. One public type per file

## Data and migrations
- Read every generated migration before applying it. Watch for drops that should be renames
- Never remove or edit a migration that has been applied to a shared database
- Production schema changes ship as a reviewed SQL script or migration bundle,
  never `dotnet ef database update` against production

## Testing
- xUnit. Integration tests use `WebApplicationFactory<Program>`
- Every bug fix comes with a test that failed before the fix

## Secrets
- Never put secrets in appsettings*.json or code
- Local secrets: `dotnet user-secrets init --project src/<App>.Api` once, then
  `dotnet user-secrets set "<Section:Key>" "<value>" --project src/<App>.Api`
- Deployed secrets come from environment variables; use `__` for nesting
  (`ConnectionStrings__Default`)

## Do not
- Do not add a NuGet package without asking
- Do not change the SDK version in global.json or the target framework
- Do not edit files under `bin/` or `obj/`

## Gotchas
- If global.json selects Microsoft.Testing.Platform, `dotnet test` options change
- For an edit it cannot hot reload, `dotnet watch` asks before restarting. `--non-interactive` restarts without asking
- <Your solution's own surprises: local containers, seed data, feature flags>

What does each part of the template do?

Header and stack line. Naming the .NET version, API style and solution file stops Claude from guessing. dotnet new webapi creates a minimal API project unless you pass --use-controllers, per the template reference, so say which one you use. The .slnx name matters because the dotnet sln docs note that dotnet new sln created .sln files only in .NET 9 and earlier; newer SDKs create .slnx.

Commands. The dotnet test reference says the command builds the solution and runs tests with either VSTest or Microsoft.Testing.Platform, and that VSTest is the default. Under VSTest, --filter with FullyQualifiedName~ matches names that contain the text. The dotnet format reference says --verify-no-changes exits non-zero if any file would change, which makes it a clean done-check. Per its reference page, dotnet watch hot reloads supported changes; for a rude edit it asks whether to restart, and with --non-interactive it restarts without asking. The --project and --startup-project flags on dotnet ef come from the EF Core CLI reference, and are needed whenever migrations live in a different project from Program.cs. Install the tool once with dotnet tool install --global dotnet-ef.

Solution structure. The three-project split keeps the domain free of framework references, a common choice that you can drop for a single-project API. Listing global.json and Directory.Build.props tells Claude where shared settings belong, so it does not copy them into every project file.

C# rules. Recent templates set <Nullable>enable</Nullable>, and the nullable reference types guide says to use the ! operator "sparingly", because each one is a place the compiler can no longer protect you. The async, options and records rules are widely used conventions; keep the ones your team follows.

Data and migrations. The EF Core migrations docs say to "always inspect the generated migrations and test them before applying to a production database", because a migration "may drop a column when the intent was to rename it". They also say applying migrations with the command-line tools "isn't ideal for managing production databases", and recommend SQL scripts or bundles for deployment. The page on managing migrations warns against removing migrations that were already applied to production.

Testing. The ASP.NET Core integration testing docs use WebApplicationFactory from the Microsoft.AspNetCore.Mvc.Testing package to host the app in memory for tests. Swap xUnit for MSTest or NUnit if that is what your solution uses; all three have dotnet new templates.

Secrets. The app secrets docs say "Never store secrets in a configuration file such as appsettings.json", describe dotnet user-secrets set for local development, and warn that Secret Manager does not encrypt values and is "for development purposes only". They also explain that the double underscore works as a nesting separator in environment variable names on every platform, where a colon does not.

Which agent mistakes does the template prevent?

Without the rule Line in the template that prevents it
dotnet ef migrations add fails because it runs against the wrong project The migration commands with --project and --startup-project
A connection string with a password added to appsettings.json "Never put secrets in appsettings*.json or code"
Nullable warnings silenced with ! everywhere "no ! without a comment saying why"
.Result or .Wait() blocking on a task inside a request "Async all the way"
A generated migration drops a column that should have been renamed "Read every generated migration before applying it"
A test filter copied from VSTest fails under Microsoft.Testing.Platform The test runner gotcha

Add rules the same way: name a mistake you have seen, then write the shortest line that stops it.

How do you adapt it to your project?

  • Controllers instead of minimal APIs: change the stack line and point the structure section at your Controllers/ folder.
  • Microsoft.Testing.Platform: if global.json sets "runner": "Microsoft.Testing.Platform", check the MTP options page and replace the filter line with the syntax your test framework supports. You can target one project with dotnet test --project <path> in that mode.
  • Single-project API: delete the Core and Infrastructure lines and drop the extra flags from the dotnet ef commands.
  • Blazor, MAUI or a worker service: keep the commands and secrets sections and replace the structure and API rules.
  • Large solutions: put a short CLAUDE.md in each project folder. Claude Code loads CLAUDE.md files in subdirectories when it reads or edits files there. The monorepo template has more on splitting rules.
  • Rules for one area: create .claude/rules/migrations.md with paths: ["src/**/Migrations/**"] in the frontmatter, so migration rules load only when Claude touches a migration file.

After saving, run /context in a Claude Code session and confirm CLAUDE.md is listed under Memory files. If you start from nothing, /init drafts a file from your solution that you can merge with these sections.

Should you write an AGENTS.md version too?

If your team also uses Codex, Cursor or GitHub Copilot, put the shared content in AGENTS.md and keep CLAUDE.md to an import plus Claude-only notes. Claude Code reads AGENTS.md by itself only when there is no CLAUDE.md or CLAUDE.local.md, and only from v2.1.277:

@AGENTS.md

## Claude Code only
- Use plan mode before changing the DbContext or any migration
- Run `/doctor prompt-audit` after editing AGENTS.md or this file

The memory docs recommend the import over a symlink when anyone clones the repo on Windows, since creating symlinks there needs Administrator rights or Developer Mode. See the AGENTS.md guide for which tools read the file, and CLAUDE.md vs AGENTS.md for the trade-offs.

How do you keep a .NET CLAUDE.md useful?

Add a line when Claude makes the same mistake twice, and delete lines it follows without being told. When you move to a new SDK, update global.json, the stack line and any command whose options changed, starting with dotnet test. /doctor prompt-audit (Claude Code v2.1.283 or later) checks your instruction files for outdated or conflicting content and proposes edits without applying them. CLAUDE.md is context, not enforcement, so block hard limits such as production database commands with a hook.

If you create .NET services often, keep the template where you can reuse it. Kipt stores prompts and Agent Skills as Markdown in a private GitHub repo you own, so you could save it as a prompt with blanks like {{database:PostgreSQL}} and fill them per solution. The C# prompts collection pairs well with it, and the Spring Boot template covers the Java side.

Questions

What should a CLAUDE.md for .NET include?

The dotnet commands to build, run, test, format and manage EF Core migrations, a map of the solution's projects, your rules for nullable reference types, configuration, secrets and async code, and the gotchas specific to your solution. Leave out general C# knowledge that Claude already has.

Which .NET version should the CLAUDE.md target?

Name the version your global.json and project files actually use. As of October 2026, .NET 10 is the current long-term support release, and .NET 11 was in release candidate. Pinning the version in CLAUDE.md stops Claude from using APIs your SDK does not have.

How do I make Claude run one .NET test?

With the default VSTest runner, dotnet test --filter FullyQualifiedName~OrderServiceTests runs tests whose full name contains that text. If your global.json selects Microsoft.Testing.Platform, the available options depend on your test framework, so write the exact filter command your project uses in CLAUDE.md.

Should Claude run dotnet ef database update?

Locally, yes. The EF Core docs say applying migrations with the command-line tools is productive for local development but not ideal for production, and that you should always inspect generated migrations before applying them to a production database. Say both in CLAUDE.md.

How long should a .NET CLAUDE.md be?

Anthropic's memory docs recommend under 200 lines per CLAUDE.md file, because longer files use more context and reduce adherence. The template here is about 60 lines. Large solutions can add a short CLAUDE.md per project folder or path-scoped files in .claude/rules.

More in Templates

All guides

Keep your prompts and skills in one place, in your own GitHub. Install every skill with one command.

Get started

Kipt is an independent product, not affiliated with or endorsed by Anthropic, OpenAI, Cursor or GitHub. Claude, ChatGPT, Codex, Cursor and GitHub are trademarks of their owners.