Open up Claude Code on a new project and start prompting. It’ll work. You’ll get code, suggestions, refactors. But watch closely and you’ll notice something: Claude is making assumptions everywhere. About your folder structure. Your testing conventions. Your preferred error handling patterns. How you name things. Where things go.
It’s like onboarding a new developer and skipping the first two weeks of context. They’ll produce code, but it won’t feel like your code.
That’s what CLAUDE.md solves. It’s a markdown file at the root of your project that gives Claude Code persistent context about how your codebase works, what you care about, and how you want things done. We’ve been refining ours at Baur Software across dozens of projects, and at this point we consider it as essential as a .gitignore. You wouldn’t skip that. Don’t skip this.
What CLAUDE.md Actually Does
When Claude Code starts a session, it reads CLAUDE.md before doing anything else. Think of it as a system prompt that lives in your repo. Everything in that file shapes how Claude interprets your requests, generates code, and makes decisions when you haven’t been explicit.
Without it, Claude falls back on general best practices. Which sounds fine until “general best practices” means it restructures your component in a pattern your team hasn’t agreed on, or writes tests using a framework you don’t use, or puts a new utility file somewhere that makes no sense in your project.
With a good CLAUDE.md, Claude arrives on day one already knowing the house rules.
What Goes Into a Good One
After months of iteration, we’ve found that an effective CLAUDE.md covers five areas. You don’t need to write a novel for each, but skipping any of them leads to friction.
1. Project Overview
A few sentences describing what this project is, who it’s for, and what it does. This sounds obvious, but it prevents Claude from making wrong assumptions about scope and intent.
## Project Overview
This is a Next.js 14 SaaS platform for managing construction project
bids. Users are general contractors and subcontractors. The app handles
bid creation, document management, and team collaboration. We prioritize
reliability and clear UX over cutting-edge features.
That last sentence matters more than you’d think. It tells Claude to make conservative choices rather than reaching for the newest API or the most clever abstraction.
2. Tech Stack and Architecture
List your stack explicitly. Don’t assume Claude will infer it from your package.json. Be specific about versions where it matters, and call out any architectural decisions that aren’t obvious from the file structure.
## Tech Stack
- Next.js 14 (App Router)
- TypeScript (strict mode)
- Tailwind CSS
- Prisma ORM with PostgreSQL
- NextAuth.js for authentication
- Zustand for client-side state
- Vitest + React Testing Library for tests
## Architecture Notes
- All API routes live in app/api/ and follow RESTful conventions
- Database queries go through service files in lib/services/, never
called directly from components or API routes
- We use server components by default, client components only when
interactivity requires it
The architecture notes section is where you save yourself the most time. Without it, Claude will scatter database calls wherever seems convenient. With it, Claude follows your patterns from the first line of code.
3. Code Style and Conventions
This is where most teams stop (if they write a CLAUDE.md at all), but it’s actually the third priority, not the first. Style matters less than architecture, but it’s still worth documenting.
## Code Conventions
- Use named exports, not default exports (except for pages/layouts)
- Prefer early returns over nested conditionals
- Error messages should be user-friendly, log technical details separately
- Component files use PascalCase, utility files use camelCase
- Keep components under 150 lines. If it's longer, break it up.
- Use absolute imports with the @/ alias
Be opinionated here. The more specific you are, the less time you spend reformatting Claude’s output to match your preferences.
4. Workflow Rules
This is the section most people miss entirely, and it’s one of the most valuable. Tell Claude how you want it to work, not just what you want it to produce.
## Workflow
- Always check for existing similar implementations before creating
new utilities or components
- When modifying existing files, preserve the current patterns even
if you'd do it differently from scratch
- Run the linter before considering any task complete
- If a change touches more than 3 files, outline the plan before
writing code
- Never delete or rename existing API endpoints without flagging it
That fourth point alone has saved us from Claude going on multi-file refactoring sprees when we asked for a small feature addition. Setting boundaries on scope is just as important as setting conventions on style.
5. Known Pitfalls and Context
Every project has landmines. Things that look like bugs but aren’t, legacy decisions that have to stay for now, areas where the obvious approach is the wrong one. Document them.
## Important Context
- The billing module (lib/services/billing.ts) integrates with a
legacy API that requires XML payloads. Do not attempt to modernize
this without discussion.
- User permissions are checked at the API route level, not in
components. Don't add client-side permission gates.
- The "projects" table has a soft-delete pattern. Always filter by
deleted_at IS NULL unless explicitly querying archived projects.
- Tests in __tests__/integration/ require a running database.
Unit tests should never touch the database.
This section is pure institutional knowledge. The kind of stuff that takes a human developer weeks to absorb. Claude can absorb it in milliseconds, but only if you write it down.
Our Template
Here’s the skeleton we start with on every new project at Baur Software. We fill in each section during project setup and update it as the codebase evolves.
# CLAUDE.md
## Project Overview
[What this project is, who it's for, what matters most]
## Tech Stack
[Frameworks, languages, key libraries with versions]
## Architecture
[Folder structure philosophy, data flow patterns, key decisions]
## Code Conventions
[Naming, formatting, component patterns, import style]
## Workflow Rules
[How Claude should approach tasks, scope boundaries, process]
## Important Context
[Landmines, legacy decisions, things that look wrong but aren't]
## Testing
[Test framework, what to test, where tests live, how to run them]
## Environment
[Environment variables, local setup quirks, deployment notes]
We keep it in version control and treat it like living documentation. When someone on the team makes an architectural decision, it goes in the CLAUDE.md the same day. When Claude does something unexpected, we figure out what context was missing and add it.
Common Mistakes
Writing a novel. CLAUDE.md should be scannable. If it’s over 500 lines, you’re probably including things that belong in actual documentation or code comments instead. Keep it focused on decisions and patterns, not explanations of how your framework works.
Being too vague. “Write clean code” means nothing. “Use early returns, keep functions under 30 lines, and prefer composition over inheritance” means everything.
Setting it and forgetting it. Your codebase changes. Your CLAUDE.md should change with it. We review ours at the start of every sprint and update anything that’s drifted.
Not including workflow rules. Style conventions are the easy part. The real value is in telling Claude how to think about your project, like when to ask before acting, how to scope changes, and where to be careful.
The Compound Effect
A good CLAUDE.md doesn’t just save you time on one task. It compounds. Every interaction Claude has with your codebase gets a little bit better because the context is there from the start. You stop correcting the same mistakes. You stop reformatting the same patterns. You stop explaining the same architectural decisions.
Over weeks and months, that adds up to a significant difference in velocity. And more importantly, the code Claude produces actually looks like it belongs in your project.
We’ve been refining this approach across every project we take on at Baur Software, and it’s become one of the first things we set up. Before the first feature, before the first component, we write the CLAUDE.md. Everything that follows is better for it.
This post is part of our series on building effectively with AI at Baur Software. Previously, we covered why your AI coding setup matters, AWS Bedrock and Claude Code as your infrastructure layer, and how to write prompts that actually work. If your AI-assisted project is getting complex enough that good tooling isn’t enough and you need good architecture, we’d love to talk.