The problem
You open Claude Code in your .NET project. You ask: “Add an endpoint for fetching user notifications.”
Claude Code gets to work. But it creates a controller while your team uses Minimal APIs. It hardcodes the connection string while you put everything in appsettings.json. It creates its own NotificationService while you already have a generic IEventHandler<T>.
Technically it works. But it doesn’t fit your project.
You correct it. Claude Code adjusts. Next question, same story. It doesn’t know how your team does things, because that’s not described anywhere — not for an AI at least.
As John Lindquist (egghead.io) puts it: “Every time an AI starts, it has no memory, no idea of what’s going on in your application.” And then developers try to steer it with rules and corrections, but they forget the most important thing: telling the AI how their application is built.
This is what’s frustrating about AI tools without context. They’re smart enough to write code, but they don’t know your project. Every session you start from scratch.
The solution: CLAUDE.md
CLAUDE.md is a Markdown file in your project that Claude Code automatically reads at the start of every session. It’s the memory of your AI assistant.
No plugin, no install, no setup. Just an .md file containing the things Claude Code needs to know about your project.
You create it with one command:
claude
/init
Claude Code scans your project and generates an initial version. But the real value is in what you add afterwards. Think of /init as a starting point — not the end result.
What to put in it?
Not a novel. Not complete documentation. Just the things you’d otherwise have to explain over and over again.
Project structure and conventions:
## Project
- ASP.NET Core 8 Web API with Minimal APIs (no controllers)
- Entity Framework Core with SQL Server
- Mediator pattern via MediatR
- All configuration via appsettings.json, never hardcoded
Patterns your team uses:
## Conventions
- Endpoints are in /Endpoints, grouped by domain
- Services always implement an interface
- Validation via FluentValidation, not data annotations
- Exceptions are handled centrally via middleware
Things Claude Code should not do:
## Don't
- Don't create controllers, we use Minimal APIs
- No Console.WriteLine for logging, use ILogger<T>
- No hardcoded connection strings
- No business logic in endpoints
Equally important: what you don’t put in it. Things Claude already knows by reading your code don’t need to be there. Standard C# conventions either. And style rules that a linter can enforce? Use a linter, not CLAUDE.md. The less noise, the better Claude follows the rules that actually matter.
The difference
Without CLAUDE.md you ask for an endpoint and get this:
[ApiController]
[Route("api/[controller]")]
public class NotificationsController : ControllerBase
{
private readonly string _connectionString = "Server=localhost;...";
[HttpGet]
public async Task<IActionResult> GetNotifications() { ... }
}
With CLAUDE.md you ask for the same endpoint and get this:
app.MapGet("/api/notifications", async (IMediator mediator) =>
{
var result = await mediator.Send(new GetNotificationsQuery());
return Results.Ok(result);
})
.WithName("GetNotifications")
.WithTags("Notifications");
No controller. No hardcoded strings. MediatR and Minimal APIs — exactly how your team does it. As if a colleague wrote it who knows how you work.
The same goes for refactoring, debugging, documentation — everything Claude Code does gets better when it knows how your project is built.
Team vs. personal
CLAUDE.md isn’t a single file. It’s a layered system:
CLAUDE.md in your project root is for the whole team. Check it into git so everyone shares the same agreements. This is where you put architecture decisions, conventions, and “don’t do” rules.
CLAUDE.local.md is just for you. This file is automatically added to .gitignore. Put your personal preferences here: your sandbox URLs, your test data, your way of working.
~/.claude/CLAUDE.md in your home directory applies to all your projects. Handy for personal style preferences you want everywhere.
This way you share team agreements via git without your personal setup getting in the way. And for larger projects you can split rules into .claude/rules/ — separate files per topic like code-style.md, testing.md, or security.md, all automatically loaded.
Claude learns on its own too
CLAUDE.md isn’t just something you write. Claude Code also has auto memory: it saves its own notes about patterns it discovers, debugging insights, and architecture decisions. These are stored in ~/.claude/projects/<project>/memory/ and automatically loaded every session.
And there’s a handy shortcut: start a line with # during a session (for example # always use MUI components) and Claude saves it immediately as a memory rule.
But the most powerful part is the feedback loop. When you correct Claude, you can say: “Add this to CLAUDE.md so you remember it.” Claude then writes the rule itself. Boris Cherny, the creator of Claude Code, recommends exactly this: “Invest in your CLAUDE.md file. After every correction, update it so you don’t make that mistake again. Claude is effective at writing rules for itself.”
This way your CLAUDE.md grows organically with your project — without turning it into a documentation project.
Tips to keep it sharp
Keep it short. CLAUDE.md is not a wiki. Aim for a maximum of 300 lines. The longer the file, the more Claude overlooks important rules. The official documentation explicitly warns about this: if your CLAUDE.md gets too long, Claude ignores half of it. Rule of thumb: if Claude already does something correctly without the instruction, remove that instruction.
Update it when you correct something. If you have to tell Claude Code a second time that your team doesn’t use controllers, put it in CLAUDE.md — or ask Claude to add it itself. You’ll never have to say it again.
Be specific. “We follow clean architecture” means nothing. “Services are in /Application/Services and always implement an interface from /Application/Interfaces” means everything.
Use imports for large projects. CLAUDE.md supports @path/to/file to include other files. This keeps the main file lean without losing context:
See @README.md for project overview and @docs/architecture.md for architecture.
Want to get started?
Open your terminal in your project:
claude
/init
See what Claude Code generates, adjust it with your own conventions, and notice the difference on your next prompt.
Yes, more context means more tokens — and that costs a bit more. But the time you save by not repeating the same corrections more than makes up for it.
Your AI is only as good as the context you give it. CLAUDE.md is that context.