If you use Claude Code for a while, you quickly realize something: the model itself is important, but the environment you give it, the boundaries you define, and the rules you set matter just as much.
At first, many people focus on “how should I write this prompt?” But once you really start using Claude Code seriously, you care more about something else:
- Does it know who you are?
- Does it know how you work?
- Does it know which rules cannot be broken?
- Does it know which actions require confirmation first?
- Can it remember these boundaries over time?
What makes Claude Code a mature tool is not just model capability. It is that there is a whole system for turning your working style into persistent structure. At a high level, that system can be divided into four layers:
CLAUDE.mdRulesMemoryHooks
This article explains all four in one pass.
Why environment setup matters more than one-off prompts
You can think of Claude Code as an assistant you hired.
On day one, you would not just tell them, “help me do things.” You would give them a handbook and explain:
- who you are
- what communication style you prefer
- which actions always require confirmation
- which mistakes have happened before and must not happen again
- where the most important project documents live
That is why, in the long run, environment setup usually matters more than a single prompt.
A prompt solves “what should we do this time?” Environment setup solves “how should we work every time from now on?”
Layer 1: CLAUDE.md
Start with the most basic piece. CLAUDE.md is essentially just a text file.
You can write instructions for Claude in it, such as:
- who you are
- what you are working on
- your communication preferences
- rules that must be followed
- special background for the current project
- where important documents or directories are
Every time Claude Code starts, this document is automatically injected into context, so the model will definitely read it.
I usually think of it as a “shared understanding file”, because that is what it really is: the standing agreement between you and the model.
What belongs in CLAUDE.md
The best things to put in CLAUDE.md are usually these kinds of information:
- identity and work background
- tone and output preferences
- global behavior rules
- important project background that comes up often
- common mistakes and how to avoid them
For example:
- your time zone
- whether you allow the model to send emails or messages directly
- which actions count as irreversible
- your habits for handling documents and files
- security practices and boundaries around sensitive information
One very important principle: keep it concise
There is one especially important principle for CLAUDE.md: keep it as concise as possible.
The reason is simple: it gets injected into context every time.
If it becomes too long, it takes up too much context space and dilutes the information that actually matters. The model is not ignoring it, but its attention becomes more spread out, so it is more likely to miss the rules you care about most.
The official recommendation is usually to stay under 400 lines.
My own habit is even more conservative: I try to keep it under 200 lines.
Common scopes for CLAUDE.md
In practice, CLAUDE.md can exist at different levels, and those levels determine its scope. The two most common ones are:
1. User Level
This is the global level.
It lives in your machine-level environment and applies to all projects you work on locally.
This is a good place for:
- your identity information
- general communication preferences
- habits that apply across projects
- global security rules
For example, if your time zone is not the default one people often assume, but Bangkok time, that fits very well at the user level, because it helps the model avoid mistakes whenever it works with dates and times later.
2. Project Level
This is the project level.
It sits inside a specific project directory and only applies to that project.
This is a good place for:
- project-specific background
- rules that only make sense in this project
- explanations of the project’s directory structure
- entry points to the project’s key documents
For example, if one project handles finance and another handles HR, the background and constraints are obviously different, so they should not live in the same global instructions.
How to decide which level to use
The rule is actually simple:
If the thing you are writing would still be true in another project, put it at the user level.
If it stops being true as soon as you switch projects, put it at the project level.
How to write the first version
There are two common ways to get started:
1. Use /init
You can run the slash command /init directly in the terminal and let Claude scan the current project to generate a basic CLAUDE.md for you.
2. Let Claude help you organize it
You can also ask Claude to look up how other people structure CLAUDE.md, ask you some questions based on your situation, and then help you organize a version that fits you.
In many cases, that is much easier than writing it from scratch yourself.
One very practical habit
As you collaborate with Claude over time, whenever you notice something that definitely needs to be remembered in the future, or something that must not go wrong again, you can ask it to write that into CLAUDE.md.
Before doing that, though, you still want to decide:
- is this a global rule?
- or a rule for the current project only?
Do not dump everything into one file.
Layer 2: Rules
Next is Rules.
The biggest difference between it and CLAUDE.md is not the file format. It is how it gets loaded.
CLAUDE.md is read no matter what you are doing.
The advantage of Rules is that they can be loaded conditionally.
In other words, a rule can be loaded only for certain paths, files, tools, or scenarios.
Why conditional loading matters
Because context space is always scarce.
If every rule gets shoved into context all the time, two things happen:
- the model carries more overhead
- truly important rules get buried
That is the value of loading rules on demand: the model sees the right information at the right time.
When to move rules from CLAUDE.md into Rules
Usually there are two situations:
1. CLAUDE.md has become too long
If your CLAUDE.md starts going beyond 200 lines, keeps growing, and the important content gets diluted, it is time to split some rules out.
2. Some rules only apply to specific paths
If you clearly know that some rules only make sense for certain kinds of files, for example:
- rules that only apply to Python scripts
- rules that only apply to a hooks directory
- rules that only apply to one subproject
then those rules belong in Rules much more naturally.
Where Rules fit best
The most typical use case is “specific situation, specific path, specific file type”.
For example:
- conventions that only apply when handling hook files
- coding rules that only matter in a certain class of scripts
- ways of working that only apply under one directory
Keeping that kind of content inside CLAUDE.md is usually not cost-effective.
Layer 3: Memory
The third layer is Memory.
Like CLAUDE.md and Rules, it also enters model context, but its core difference is this:
CLAUDE.md is something you define deliberately.
Memory is more like notes Claude writes for itself during collaboration.
What goes into Memory
When Claude judges that something is worth remembering, or should be kept for a while, it writes that information into Memory.
Common examples include:
- a way of working you corrected
- a newly added preference
- temporary state in the current project
- something you did not finish today and need to continue tomorrow
- who you have been collaborating with recently
- personal information or context that only came up recently
In other words, Memory is closer to dynamic knowledge than long-term policy.
How it differs from the first two layers
A simple distinction is:
CLAUDE.md/Rules: long-term, policy-like, explicit rulesMemory: temporary, dynamic, newly learned context during work
If something only matters for the next few days, or keeps changing as the project evolves, it usually belongs in Memory, not in a permanent rule file.
Memory can also be written manually
Even though Memory can be maintained automatically, you can also explicitly tell Claude things like:
- please remember what I need to do tomorrow
- please remember whose status I need to follow up on
- please remember the key milestone for this project this month
It can write that into Memory for you.
You can also use the slash command /memory to see what memories currently exist and edit or delete them manually.
That said, I personally do not maintain it manually too often, because Claude itself can periodically reorganize these memories and clear out what has gone stale.
Layer 4: Hooks
The last and most advanced layer is Hooks.
Everything before this, including CLAUDE.md, Rules, and Memory, is still ultimately natural-language guidance.
You write rules, and the model usually follows them, but it is still operating by interpreting them first and then acting.
As long as the rule lives in natural language, a few problems remain:
- the model may occasionally miss it
- too many rules can dilute attention
- in some situations, the model may decide the rule is not important enough
That is not because you wrote the rule badly. It is because natural-language rules are hard to enforce with 100% reliability.
What Hooks really are
Hooks are no longer natural-language instructions. They are scripts.
They are event-triggered, program-level enforcement logic.
Once a certain event happens, that logic will run. It will not be skipped because the model decided to ignore it.
That is the key value of Hooks:
they turn “should follow this” into “must execute this”.
When you should upgrade to Hooks
If you notice that a rule is already written in CLAUDE.md or Rules, but Claude still occasionally fails to follow it, and missing it carries real risk, then that rule should probably become a Hook.
In simple terms:
- low-risk behavior: use rules
- high-risk behavior: use
Hooks
The most typical Hooks scenarios
The most obvious examples are actions you absolutely do not want to get wrong, such as:
- requiring confirmation before sending an email
- requiring confirmation before sending Slack, Outlook, or Gmail messages
- intercepting dangerous file deletions
- blocking the outbound leak of passwords or API keys
If those are only written as natural-language rules, the model can still make a mistake someday.
If they are implemented as Hooks, the event gets intercepted every time.
That is a real program-level safety barrier.
Common trigger points for Hooks
Hooks can be attached at different stages, for example:
- injecting reminders at the start of a conversation
- checking conditions before a tool runs
- validating results after a tool runs
You do not necessarily need to know the formal terminology yourself.
Often, as long as you can describe the requirement clearly and ask Claude whether it should become a hook, it can help you design it.
You can also use the slash command /hook to inspect which hooks are currently configured.
A more practical way to get started
If you want to connect all four layers together, I usually recommend this order:
Step 1: use /init to generate a basic CLAUDE.md
Do not try to hand-write a huge complete rule document at the start.
Let Claude scan the project and generate a starting point, then iterate from there.
Step 2: add things as you work
As you collaborate, whenever you notice:
- this must be remembered in the future
- this mistake must not happen again
- this preference will keep applying every time
then ask Claude to add it to CLAUDE.md.
Step 3: move things into Rules once CLAUDE.md grows
Once CLAUDE.md gets longer and longer, and the model no longer reliably follows every rule, split things out:
- which rules are global?
- which ones only apply to certain paths?
Move the second kind into Rules so they load conditionally.
Step 4: upgrade high-risk rules into Hooks
If some rules still get missed even after you wrote them down, and the cost of missing them is high, do not stay in the natural-language layer. Upgrade them into Hooks.
That is the point where “reminder” becomes “enforcement”.
Step 5: let Memory handle temporary state
For things that expire, change frequently, or are not long-term policy, do not shove everything into CLAUDE.md.
It is usually cleaner to let Memory hold things like:
- current project progress
- recent collaborators
- newly added preferences
- short-term plans and to-dos
That keeps context cleaner and makes the model behave more consistently.
What each layer should store
If you want a quick mental model, use this:
CLAUDE.md: long-term shared understanding, global instructions, foundational project backgroundRules: specialized rules loaded by path or scenarioMemory: dynamic knowledge, temporary state, things learned recentlyHooks: program-level enforcement for high-risk actions
Closing
Many people treat Claude Code as “a chat interface that can write code”. But once you use it deeply, it feels more like a long-term intelligent workstation.
The key is not only how you phrase each instruction. It is whether you have given it a stable, clear, and accumulative environment.
Once you build these four layers:
CLAUDE.mdRulesMemoryHooks
the quality of collaboration between you and the model usually improves very noticeably.
Because you are no longer re-explaining from scratch who you are, how you work, and what must not happen every single time. You have actually turned those things into part of the environment.
That is the key step in turning a strong model into a mature tool.