Mo Sharif
Back to writing

CLAUDE.md Best Practices: Write Rules That Help

In this article

The instruction worth keeping is usually the one that prevents a plausible mistake. “Write clean code” does not help much. “This site has one theme; do not add dark-mode rules” changes the work immediately.

A CLAUDE.md file

is a markdown instruction file that gives Claude Code persistent project context, including conventions and constraints that would otherwise need to be explained again.

For this portfolio, the valuable context is small: where copy lives, how the theme works, which checks to run and which tidy-looking refactor has already caused a regression.

An instruction earns its place when it prevents a likely mistake or points to a non-obvious source of truth. A useful test is whether the agent would take a different action without it. If the answer is no, the line probably belongs in ordinary documentation.

I would keep “edit shared copy in the content resource” before “this project uses React.” The first names an ownership rule. The second is something the imports already explain.

Anthropic's memory documentation describes these files as context rather than enforcement, recommends concise instructions and gives an under-200-line target. That is guidance, not a challenge to fill 199 lines.

A focused portfolio instruction file should name the build checks, content ownership and design constraints that affect ordinary changes. The example below is an abbreviated pattern based on this repository, not a frozen copy of its complete current instructions.

Markdown
# Portfolio working notes

This repository is the personal portfolio, not the Codelit app.

## Verification

- Run npm run quality before proposing a release.
- Run npm run lint:posts after editing MDX.
- Check the changed routes at desktop and mobile widths.

## Sources of truth

- Shared copy and page metadata: src/resources/content.js.
- Design tokens and shared styles: src/resources/custom.css.
- Articles: src/app/blog/posts/\*.mdx.

## Constraints

- Keep the black-and-white single theme consistent across routes.
- Do not introduce motion as a default polish step.
- RouteGuard must remain synchronous; a mount gate caused a load flash.
- Use GFM tables in MDX, not the client-side Table component.
- Dependency changes must keep both lockfiles in sync.

The commands are concrete. The file paths save a search. The constraints explain what “consistent” means for this product.

The earlier version of this article included an old dual-theme, cursor-spotlight design as though it still governed the site. It does not. That is a useful example of why a copied instruction file needs a review date.

A regression note preserves the reason behind a choice that otherwise looks arbitrary. Without the reason, a future edit can reasonably undo the fix. The best note explains the symptom and the constraint without turning into a transcript of the original debugging session.

The portfolio's RouteGuard is the example I would keep. Delaying its children behind a mount effect introduced a loading flash and meant sibling effects could run before the expected content existed. “Keep it synchronous” is useful because it names a behavior to preserve.

A second example is MDX tables. A component can be legal JSX and still receive a malformed client-side prop. “Use GFM markdown tables” prevents that particular failure and keeps the content portable.

That is also how I think about the architecture canvas: document the constraint the implementation satisfies, not only the library it uses.

For a repository used by multiple agents, keep the shared rules in one canonical file and use the supported import mechanism for each tool. This reduces duplicate maintenance. It does not mean every agent supports the same format or interprets every instruction identically.

For Claude Code, the documented wrapper is:

Markdown
@AGENTS.md

Add Claude-specific guidance below the import only when there is a real difference to describe. Check /context to confirm the expected memory files loaded. Importing another file organises the instructions; it does not make the imported text free context.

Do not copy a file into a second name and assume it will stay current. Two independent versions eventually disagree about something important, usually a command or a restriction.

Instruction files should not contain secret values, an exhaustive dependency inventory or rules already expressed unambiguously by tooling. Personal local files are useful for preferences, but being gitignored does not prevent their contents from reaching the model.

MaterialBetter home
Formatting rulesFormatter and lint configuration
CredentialsSecret manager or environment configuration
Full architecture referenceProject documentation, linked when needed
Release checklistA scoped skill or workflow
Rules for one directoryPath-scoped instructions
Access restrictionsPermissions, sandbox and server-side checks

This does not require deleting every command an agent could discover. A short pointer can be worthwhile when it saves a predictable mistake, such as running the wrong quality check.

The line I would remove first is the one nobody can explain. If its purpose is only “we always include this in templates,” it has not earned the space.

A rule should become a test when software can decide whether it holds, and a hook can run that test at the appropriate lifecycle event. Neither replaces the underlying access controls. An instruction to validate output is weaker than a validation step the application actually executes.

That boundary matters in Codelit's structured-output pipeline: describing the desired shape is not the same as rejecting an invalid result.

For the portfolio, frontmatter parsing and internal-link validation are scriptable checks. Whether a headline sounds like me needs editorial judgement. Those should not be enforced by the same mechanism.

I cover the distinction more fully in choosing skills, subagents, hooks and MCP. Use a hook for a well-defined event, then test that it really runs and fails as intended. A misconfigured check can create false confidence.

Review the instruction file alongside the change that invalidates it. A theme rewrite, package-manager change or new release workflow should trigger an instruction review. Otherwise the next agent begins with confident directions for a repository that no longer exists.

After a correction, I ask three questions:

  1. Was the mistake likely enough to recur?
  2. Is the reason missing from the code or existing documentation?
  3. Can a tool prevent it more reliably than another sentence?

Add a line when the answers justify one. Delete it when the constraint disappears.

The goal is not the shortest possible CLAUDE.md. It is a file where every line still describes how the work should happen today.

Questions people actually ask

What belongs in a CLAUDE.md file?
Put in the facts that change how an agent should work in this repository: verification commands, sources of truth, important constraints and regression history that is not obvious from the code. Keep procedures and narrow rules elsewhere so the main file stays useful.
Does Claude Code read AGENTS.md automatically?
Claude Code's documentation says it reads CLAUDE.md rather than AGENTS.md. For a mixed-agent repository, a CLAUDE.md file can import AGENTS.md so shared instructions have one source. Verify the loaded files in the session instead of assuming the wrapper works.
How long should a CLAUDE.md file be?
Keep it short enough that each rule has an identifiable purpose. Anthropic recommends targeting under 200 lines per file, but that is guidance rather than a hard limit. Move area-specific material into scoped rules and occasional procedures into skills.
Should secrets go in CLAUDE.local.md?
No. A gitignored local instruction file can hold personal workflow preferences, but it still enters the agent's context. Keep credentials in the appropriate secret store or environment configuration and avoid placing their values in any instruction file.
Can CLAUDE.md enforce a safety rule?
An instruction file guides the model; it is not an enforcement boundary. Use permissions, sandboxing and service-side authorization for access restrictions. Hooks can add checks at specific events, but their matching and failure behavior also need testing.