Claude now has at least seven places you can put an instruction: profile preferences, Styles, Projects, Skills, CLAUDE.md, hooks, connectors, and subagents. Every one of them is documented on its own. What's missing is the page that says which one to use for the rule you're about to write, so most people pick one and put everything there.
That fails quietly. A "never commit to main" line works for the first hour of a session and gets missed in the fourth. A twelve-step release checklist in CLAUDE.md costs tokens in every session even though you release once a week. "No emojis" copied into nine different Projects ends up worded nine different ways.
This guide gives you one decision rule per destination and a flowchart to route any instruction. If you'd rather paste your current rules and have them sorted, the Claude Instruction Router does it in your browser.
The one question that sorts almost everything
Ask two things about any instruction:
- When does it need to apply? Always, only for one kind of task, or only when a specific action happens?
- What happens if Claude misses it once? Mildly annoying, or genuinely bad?
The answers map almost directly to a destination:
| Applies... | If missed once... | Put it in |
|---|---|---|
| To you, everywhere | Annoying | Profile preferences / user-level CLAUDE.md |
| To one body of chat work | Annoying | A Project |
| To one codebase, most sessions | Annoying | CLAUDE.md |
| Only for one kind of task | Annoying | A Skill |
| On a specific action, every time | Bad | A hook |
| Needs live data from another system | (can't be done with text) | A connector / MCP server |
| A separate job with its own context | n/a | A subagent |
| Things the model already does | n/a | Nowhere: delete it |
The rest of this post is the reasoning behind each row, and the mistakes that show up when a rule lands in the wrong one.
Profile preferences and Styles: things about you
What goes here: how you like answers. Length, tone, formatting, language, your role, what to skip. "I'm a backend engineer; skip beginner explanations." "No emojis." "British spelling."
Where it lives: in claude.ai, Settings → Profile has a personal-preferences field that applies to every chat, and Styles let you switch tone per conversation. In Claude Code, the equivalent is your user-level ~/.claude/CLAUDE.md, which loads in every repository.
The mistake: copying personal preferences into each Project or each repo's CLAUDE.md. They drift, they get committed for teammates who don't share them, and you pay for them twice when both a project and your profile say the same thing.
Projects: context for a body of work in chat
What goes here: everything Claude should know for one client, product, book, course, or campaign in claude.ai. Brand voice, audience, terminology, reference documents, what's been decided.
Where it lives: Projects → Instructions for the short guidance, and project knowledge for the files.
Why it beats re-uploading: Anthropic says project content is cached and counts less against your usage limits when you reuse it. If you attach the same style guide to every new chat, you pay full price each time. (That's one of the biggest hidden drains covered in why you keep hitting Claude's usage limit.)
The mistake: using a Project for a procedure. "When I ask for a proposal, follow these 14 steps" works inside that one Project and nowhere else. If the procedure is useful across projects, it's a Skill.
CLAUDE.md: facts about a codebase
What goes here: short, durable facts about a repository that the agent needs in most sessions and can't reliably infer. The build and test commands. The package manager. Conventions that contradict the framework's defaults. Directories that must not be touched. ("Use pnpm. Run pnpm test:unit before finishing. API handlers validate input with zod.")
Where it lives: CLAUDE.md at the repo root (or AGENTS.md, which many tools read and CLAUDE.md can reference). Rules that only matter for one part of the tree can be scoped to those paths so they load only when relevant.
The test for every line: would it be true and useful in every session in this repo? CLAUDE.md is loaded at the start of each session and billed on every turn, so a line that matters once a month is a tax the other 29 days. The CLAUDE.md guide and the AGENTS.md bloat linter go deeper on trimming.
The mistakes: procedures (move to a Skill), hard prohibitions (move to a hook), descriptions of what's obvious from the code ("This is a Next.js app"), and generic advice ("write clean code").
Skills: how to do one kind of task
What goes here: a procedure that only matters when a particular task comes up. Cutting a release. Writing a migration. Drafting a grant report in your organization's format. Reviewing a PR against your team's checklist. Skills can also bundle scripts and templates the procedure needs.
Where it lives: a folder with a SKILL.md file. In Claude Code, .claude/skills/<name>/SKILL.md in the repo or your home directory. In claude.ai, skills are uploaded in settings. Note that these are managed separately: a skill uploaded to claude.ai isn't automatically available in Claude Code.
Why it's cheap: only the skill's short description is loaded up front. The body loads when Claude decides the task matches. A 2,000-token release procedure costs almost nothing in sessions where you aren't releasing, which is the whole argument for moving procedures out of CLAUDE.md.
The catch: the description is what makes it trigger. "Release helper" won't fire; "Use when cutting a release, bumping the version, or updating CHANGELOG.md" will. The SKILL.md Builder lints descriptions for exactly this, and this post covers why skills fail to trigger.
Hooks: rules that must hold every time
What goes here: anything where "Claude followed it most of the time" isn't good enough. Never commit to main. Never read .env. Always run the formatter after an edit. Run the tests before the session ends. Block rm -rf outside the project.
Where it lives: Claude Code's settings (.claude/settings.json), under hooks tied to lifecycle events such as before a tool runs, after it runs, or when the session stops. A hook is a command that runs on every matching event and can block the action.
Why text isn't enough: an instruction is context. The model weighs it against everything else in a long session, and occasionally it loses. A hook isn't weighed: it runs. If you've ever written "IMPORTANT: NEVER" in capital letters, that line probably wants to be a hook. The Hooks Builder generates the config, and 7 hooks worth having covers the common ones.
The mistake in reverse: turning preferences into hooks. A hook that blocks every edit without a docstring will make you miserable. Hooks are for the short list of things that are actually costly to get wrong.
Connectors and MCP servers: access, not instructions
"Check the Jira ticket before starting" can't work as an instruction if Claude can't reach Jira. No amount of wording fixes missing access. That needs a connector in claude.ai (Settings → Connectors) or an MCP server in Claude Code. Once access exists, the instruction about when to use it can go in CLAUDE.md or a Skill. More in MCP vs Skills and the MCP config guide.
Subagents: a separate job with its own context
"Get an independent review of security-sensitive changes" or "research the three libraries in parallel" describe a job that benefits from a clean context, so its file reads and dead ends don't flood the main conversation. In Claude Code that's a subagent defined in .claude/agents/. See when to spawn subagents for when this pays off and when it's just overhead.
The bin: instructions the model already follows
"Write clean, readable code." "Be accurate." "Think step by step." "Follow best practices." These change nothing about behavior and cost tokens in every session. Worse, they dilute the rules that do matter: when a file has 40 lines and three of them are critical, the three are harder to find. Delete them.
Worked example
Here's a typical "everything in one file" setup, routed:
| Instruction | Destination | Why |
|---|---|---|
Use pnpm, not npm. Run pnpm test before finishing. | CLAUDE.md | Codebase fact needed most sessions |
| Never commit directly to main. | Hook | Must hold every time |
| Always run prettier after editing a file. | Hook | Should happen automatically, not be remembered |
| Write clean, readable code and follow best practices. | Delete | Default behavior |
| I prefer short answers with no emojis. | Profile / ~/.claude/CLAUDE.md | About you, not this repo |
| Our brand voice is warm and plain-spoken. | Project | Context for chat writing work |
| When cutting a release: bump version, update CHANGELOG, tag, push. | Skill | Only matters when releasing |
| Check the Linear ticket for acceptance criteria. | Connector + a line in CLAUDE.md | Needs access first |
API handlers live in src/server/routes and validate with zod. | CLAUDE.md | Non-obvious convention |
| Get an independent review of security-sensitive diffs. | Subagent | Separate job, clean context |
Never read or print .env files. | Hook | Protects secrets |
Eleven lines, seven destinations. Only three of the eleven belong in the file that loads every session. The rest are either enforced more reliably, loaded only when needed, or gone.
That table is the sample input in the Instruction Router. Paste your own CLAUDE.md, Project instructions, or custom instructions and see how they sort. It's a keyword heuristic, so it explains each decision and flags the ones it isn't sure about. For those, go back to the two questions: when does this apply, and what happens if it's missed once.