Skip to content

Foundational elements

Most efficiency problems in Claude Code come from using the wrong primitive for the job. A rule in CLAUDE.md that should have been a Skill costs tokens on every session forever. A Skill that should have been a subagent reasons in the main thread instead of an isolated context. An agent that should have been a settings.json rule can be talked out of doing its job.

This page does two jobs. It’s the decision hub for the four primitives that shape how Claude Code behaves — what each does, where it lives, the trade-offs between them, and how to pick the right one for a given rule. It’s also the map to everything else in Foundations: the capabilities you add to a project and the disciplines that keep it lean, each with its own page.

The rest of this group splits cleanly in two.

Behaviour-shaping primitives — the four mechanisms that change how Claude Code acts: CLAUDE.md, subagents, skills, and hooks. These are the ones you weigh against each other when deciding where a rule belongs. The decision framework on this page is about these four and only these four.

Capabilities and practices — everything a configured project leans on once the four are in place: the memory conventions, slash commands, plugins, pruning, MCP servers, and the scheduled-versus-on-demand split. These aren’t competing choices for the same rule. They’re capabilities you add when you need them and disciplines you run on a cadence, and each has its own page.

Claude Code gives you four mechanisms for shaping how it behaves. The decision framework in the rest of this page is about choosing between these.

CLAUDE.md is a system prompt. Everything in it loads on every session and shapes the main thread for everything you do. You pay context tax on every message.

Subagents are isolated workers with their own context windows. They cost zero on the main thread, can be pinned to cheaper models, and are triggered by their description field. The main thread only sees their final summary.

Skills are loaded on demand. The name and description load eagerly so Claude knows the skill exists; the body only loads when the skill is invoked. They run inline on the main thread.

Hooks are lifecycle triggers — pre-commit, post-edit, and similar events that fire automatically. The right answer when you want deterministic automation rather than guided behaviour.

The choice between the primitives is a question of when the rule should apply and where the work should happen.

You want…Reach for…Because…
Behaviour that applies to every interactionCLAUDE.md ruleIt shapes every read, edit, and query — worth the per-session cost
A repeatable specialist task in an isolated contextSubagentThe work doesn’t belong on the main thread; it needs its own context window and often its own model
A workflow available on demand, but not always loadedSkillThe instructions only matter for some tasks; loading them on every session isn’t worth the context cost
A deterministic action triggered by an eventHookNot guidance, automation

The single most useful question when you’re unsure: should the main thread reason about this, or should it delegate? If the main thread should reason, it’s either a CLAUDE.md rule (always-on context) or a skill (on-demand context). If it should delegate, it’s a subagent or a hook.

The trade-offs that matter, side by side:

CLAUDE.mdSubagentSkill
Context costLoads on every messageZero on main threadname + description (~100 tokens) load eagerly; body only on invocation
ModelInherits main threadPinnable to Haiku, Sonnet, or OpusCan override main thread when invoked
ScopeShapes all behaviourTriggered by description for specific tasksTriggered when description matches the task
Context windowShared with main conversationFully isolated; only the summary returnsShared with main thread
Tool accessMain thread inherits all toolsRestricted via tools: fieldRestricted via allowed-tools: field

The cost asymmetry is the line that does the most work. Putting subagent instructions into CLAUDE.md instead of an agent file would load them on every session — including the trivial queries where the agent’s job doesn’t apply. The agent file means those instructions only exist when the agent is invoked, in its own isolated window, often on a cheaper model. Multiplied across the sessions a project sees, that’s the difference between context cost that pays for itself and context cost that doesn’t.

Before adding any new rule, agent, or skill, walk these questions in order:

  • Does this rule need to apply to every interaction in this repo? → CLAUDE.md.
  • Is this a repeatable specialist task (review, compress, draft)? → Subagent.
  • Is this a workflow you want available on demand but not always loaded? → Skill.
  • Is this a deterministic action triggered by an event? → Hook.

If you find yourself adding behavioural rules to CLAUDE.md that only apply to some tasks, you’ve reached for the wrong primitive. Move it to a Skill.

If you find yourself building a subagent for something the built-in agents already cover (Explore, Plan, General-purpose), don’t. Use the built-ins first — reach for a custom subagent only when the built-ins genuinely don’t fit.

Each primitive has a user-level home (applies across all your projects) and a project-level home (committed with the repo, applies to everyone working on it). The pattern is consistent:

PrimitiveUser-levelProject-level
CLAUDE.md~/.claude/CLAUDE.md<repo>/CLAUDE.md
Subagents~/.claude/agents/*.md<repo>/.claude/agents/*.md
Skills~/.claude/skills/<name>/<repo>/.claude/skills/<name>/
Settings~/.claude/settings.json<repo>/.claude/settings.json

The principle is scope of relevance dictates location. User-level for things that span repos. Project-level for things that would be noise outside that codebase.

There’s also a local-only tier for personal overrides that shouldn’t be committed (.claude/settings.local.json, CLAUDE.local.md); reach for it when you have personal preferences for one project that the rest of the team shouldn’t inherit.

When the same rule exists at multiple scopes, more specific wins. A project-level setting overrides your user-level setting; a local-only setting overrides both.

Foundations continues with a page for each primitive, then the capabilities and practices that build on them.

The four primitives:

  • CLAUDE.md — what belongs in the file, the imports system, anti-patterns, maintenance.
  • Subagents — frontmatter, three agent templates, anti-patterns.
  • Skills — progressive disclosure, two skill templates, anti-patterns.
  • Hooks — what they are, and when to reach for them.

Capabilities and practices:

  • Dynamic workflows — orchestrating many subagents at scale for fan-out, adversarial verification, and pipeline-based multi-stage work.
  • Memory — Claude Code’s user-level auto-memory and the project’s manual decision log, and when to use which.
  • Slash commands — triggerable markdown shortcuts, the dynamic-element syntax, and the line where a command should graduate to a skill.
  • Plugins — bundling skills, commands, hooks, and MCPs into a single installable unit.
  • Pruning — cutting context, skills, and rules that no longer earn their keep, and the cadence to run it on.
  • MCPs — the Model Context Protocol servers worth adding to a project: live docs, GitHub, visual UI feedback, database access.
  • Scheduled vs on-demand — the axis between work that runs on a clock and work that happens at your keyboard.

If you’re new to Claude Code configuration, read the pages in order. If you’re returning, jump to the page that matches the question you’re trying to answer.

For a worked example of all four primitives applied together — for personal operational work rather than a product build — see the Command Centre.