Skills vs subagents vs commands: which to use for what
One of the three stopped being a separate category. The four questions that pick the right mechanism, and the precedence table that flips order between them.
- claude code
- skills

Contents
- Four questions that decide
- Skill or subagent: the question is about context
- Skill or hook: request against guarantee
- CLAUDE.md or skill: always against sometimes
- The same request, across all four mechanisms
- Precedence: four models in the same product
- What each one costs in context
- Combinations that work
- Frequently asked questions
- Sources
One of the three stopped existing as a separate category. A custom command is now a skill, and the commands documentation points straight at the skills documentation. A file at .claude/commands/deploy.md and a skill at .claude/skills/deploy/SKILL.md create the same /deploy and behave the same way.
That leaves a real choice, and it runs wider than two options: skill, subagent, hook or CLAUDE.md. Four questions settle almost every case.
Four questions that decide
Before the tables, the short path. Answer in order and stop at the first yes.
1. Does it have to happen every time, without depending on the model agreeing? That is a hook. It fires on the lifecycle event, whatever the agent decides.
2. Will it read many files or produce output you will not reread? That is a subagent. The work happens in a separate context and only the summary returns.
3. Does it hold for every task in the project, all the time? That is CLAUDE.md, or a rule in .claude/rules/ if the scope is per path.
4. Is it knowledge or a procedure you use sometimes? That is a skill.
And a fifth case falls outside all four: if what you lack is access to data or an external action, the mechanism is MCP, covered in MCP in practice.
The documentation organizes the same decision by trigger, which works better day to day:
| When this happens | Add |
|---|---|
| The agent gets the same convention wrong twice | A line in CLAUDE.md |
| You type the same prompt to start a task | A skill you invoke |
| You paste the same procedure into the chat for the third time | A skill |
| You copy data from a tab the agent cannot see | An MCP server |
| A side task floods the conversation with disposable output | A subagent |
| You want something to happen every time, with no prompt | A hook |
| A second repository needs the same configuration | A plugin |
Skill or subagent: the question is about context
Skills and subagents look like alternatives and solve different problems. A skill is reusable content loading into the context you already have. A subagent is an isolated worker with its own window.
| Aspect | Skill | Subagent |
|---|---|---|
| What it is | A reusable instruction, body of knowledge or flow | An isolated worker, with its own context |
| Core benefit | Sharing content across contexts | Isolation: the work stays out of your window |
| Context impact | Adds to your main window | Uses a separate window, with its own input and output |
| Best for | Reference material, an invocable flow | A task that reads many files, parallel work |
Knowing what enters a subagent at birth is worth the time, because the list surprises people:
- Its own system prompt, and not the whole Claude Code one
- The delegation message the main agent wrote
- The entire
CLAUDE.mdhierarchy, personal file and managed policies included - A snapshot of the git state, taken at the start of the parent session
- The complete content of the skills listed in its
skills:field
Two practical consequences. The first: a subagent starts with no empty context. It carries your whole CLAUDE.md, so a bloated file makes every delegation more expensive. The second: a skill named in the skills: field enters whole, and not the description alone, which is excellent when you want the worker to know something, and expensive if you list too many.
The built-in Explore and Plan agents skip CLAUDE.md and the git state. That is why they come out cheaper than a custom subagent for the same search.
A fork is the special case worth knowing. It inherits the whole conversation instead of starting from zero, giving up input isolation and gaining something else: since its system prompt and tools match the parent's, its first request reads the parent's cache. For a side task needing the same context, forking costs less than standing up a new subagent.
In the cost measurement across 48,000 real turns, a subagent turn cost 3.3 to 5.2 times less than a main-conversation turn, controlling for model. The criterion for when to delegate sits in subagents: when to delegate.
Skill or hook: request against guarantee
This is the distinction most people get wrong, and the documentation is direct about it.
An instruction such as "never edit .env", written in CLAUDE.md or a skill, is a request, not a guarantee. A PreToolUse hook that blocks the edit is enforcement. If the rule has to hold every time, it becomes a hook, and not a prompt instruction.
| Aspect | Hook | Skill |
|---|---|---|
| What runs | A shell command, HTTP request, prompt or subagent | An instruction the agent reads and follows |
| Triggered by | A lifecycle event | You typing /name, or the agent matching the description |
| Determinism | Always fires on its event | The agent interprets; the result varies |
| Context cost | Zero, unless it returns output | The description each session, the content when used |
The corollary runs useful in the other direction: hook output enters the context. A PostToolUse that runs your linter returns the result as text the agent reads. The full mechanics sit in hooks in Claude Code.
The rule I use: a process that changes the state of the world and needs a guarantee is a hook. A process that needs judgment is a skill.
CLAUDE.md or skill: always against sometimes
Both hold instructions, and the difference is when they load.
| Aspect | CLAUDE.md | .claude/rules/ | Skill |
|---|---|---|---|
| Loads | Every session | Every session, or on opening a matching file | On demand |
| Scope | The whole project | Can be limited by path | Specific to the task |
| Fires a flow | No | No | Yes, with /name |
CLAUDE.md holds what the agent has to know at all times: code conventions, build commands, architecture. A skill holds what it needs sometimes: API documentation, a release checklist, a style guide.
The recommended target remains under 200 lines for CLAUDE.md. Once it grows, the overflow goes to a path-scoped rule or to a skill. The full anatomy sits in CLAUDE.md: the anatomy.
The same request, across all four mechanisms
An abstraction gets clear with one case. Take "the tests have to pass before a commit" and see what each mechanism delivers.
As CLAUDE.md:
## Conventions
- Run `npm test` before any commit.It delivers a request that holds in every session and costs on every request. The agent tends to comply, and nothing stops it skipping the step once the context fills up.
As a skill:
---
name: commit
description: Runs the tests and commits if they pass
disable-model-invocation: true
---
1. Run `npm test`
2. If it fails, show the output and stop
3. If it passes, write the message and commitIt delivers a procedure with judgment, happening when you type /commit and not before. Zero cost until invocation, because disable-model-invocation keeps the skill out of the listing.
As a hook:
{
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{ "type": "command", "command": ".claude/hooks/test-before-commit.sh" }]
}]
}
}It delivers a guarantee. The script inspects the command, runs the tests and exits with code 2 to block. It happens every time, whatever the agent thinks, and costs zero context unless it returns text.
As a subagent: it does not apply. The problem here is determinism, not context volume, and a subagent solves no determinism problem. Recognizing where a mechanism does not fit saves more time than choosing well among the ones that do.
Reading the first three options together: CLAUDE.md is what the agent knows, a skill is what you fire, a hook is what happens regardless. All three can coexist on the same subject, in different roles. The walkthrough for writing a skill sits in how to write your first Agent Skill.
Precedence: four models in the same product
Here is the part nobody writes down, and it explains odd behavior when the same name exists in two places. Each mechanism resolves conflict its own way.
| Mechanism | How it resolves | Order |
|---|---|---|
CLAUDE.md | Adds. Every level contributes at once | No order: it is additive |
| Skill | Overrides by name | managed › personal › project |
| Subagent | Overrides by name | managed › the --agents flag › project › personal › plugin |
| MCP | Overrides by name | local › project › user |
| Hook | Joins. All of them fire, wherever they come from | No order: all run |
The two middle rows hold the difference. With skills, personal beats project. With subagents, project beats personal. The order inverts between two mechanisms living side by side in .claude/.
That has a practical effect. Your personal deploy skill overrides the one the team versioned in the repository, and you may not even remember creating it. Your personal reviewer subagent, though, does not override the project's: there the team wins.
When behavior fails to match expectation, the right question is which of the definitions carrying that name is in force. For a plugin skill, the plugin:name namespace avoids the conflict altogether, as detailed in plugins and marketplaces.
What each one costs in context
No choice here is neutral. The official cost table:
| Mechanism | When it loads | What it loads | Cost |
|---|---|---|---|
CLAUDE.md | Session start | The whole content | On every request |
| Skill | At start and on use | The description at start, the content on use | Low |
| MCP | Session start | Tool names; schemas on demand | Low until used |
| Subagent | On creation | Its own context | Isolated from the session |
| Hook | On trigger | Nothing, it runs outside | Zero, unless it returns output |
Two levers come out of that. disable-model-invocation: true takes the skill out of the initial listing: it costs zero until you type /name, which suits anything with a side effect. And CLAUDE.md is the one item paying on every request, which makes each of its lines a recurring decision rather than a one-off. The breakdown sits in why your agent forgets.
Combinations that work
The mechanisms do not compete. A mature configuration uses several, each on what it does best.
| Pattern | How it works |
|---|---|
| Skill + MCP | MCP gives the connection; the skill teaches how to use that system well |
| Skill + subagent | An /audit skill fires security, performance and style subagents in parallel |
CLAUDE.md + skill | The file says "follow our API conventions"; the skill holds the full guide |
| Hook + MCP | A post-edit hook sends an external notification when a critical file changes |
The most common complete configuration is unremarkable and it works: CLAUDE.md with the conventions, a skill with the deploy flow, MCP for the database, and a hook running the linter after each edit.
Frequently asked questions
Do custom commands still exist?
They exist and keep working, though they stopped being a separate category: they became skills. Files in .claude/commands/ still create the command named after the file. For new content, a skill gives you more: a folder for supporting files, frontmatter controlling who invokes it, and automatic loading when relevant. The full grammar sits in writing your own slash commands.
When does a skill become a subagent?
When the work generates context you will not reread. A skill that has the agent read thirty files leaves all thirty in your window for the rest of the session. The same work in a subagent returns the summary alone. A middle ground exists too: context: fork in the frontmatter runs the skill in an isolated context.
Why is my project skill going unused?
A personal skill with the same name is the usual cause. With skills, the order runs managed, then personal, then project, so the personal one wins. Checking ~/.claude/skills/ before investigating the repository file is worth the minute. With subagents the order is the opposite, which trips up anyone who learned one and assumed the other.
Do I have to pick just one?
No, and good configurations combine several. The question is which mechanism solves each need: a guarantee is a hook, isolation is a subagent, permanent context is CLAUDE.md, and on-demand knowledge is a skill. The operating checklist that ties it together sits in Claude Code in production.
Sources
- Anthropic — Claude Code Docs: Extend Claude Code. Accessed 20 August 2026.
- Anthropic — Claude Code Docs: Create custom subagents. Accessed 20 August 2026.
- Anthropic — Claude Code Docs: Extend Claude with skills. Accessed 20 August 2026.
- Anthropic — Claude Code Docs: Automate actions with hooks. Accessed 20 August 2026.
- Anthropic — Claude Code Docs: How Claude remembers your project. Accessed 20 August 2026.
Verified on 20 August 2026.
Review trigger: revisit when (a) skill or subagent precedence changes order, (b) .claude/commands/ gets deprecated, or (c) an extension mechanism appears beyond CLAUDE.md, rules, skills, subagents, hooks, MCP and plugins.
Read next
Motion •
Motion Design for the Web: The Complete Guide
Scroll, text, images and video: the complete catalog of motion techniques for the web, with implementation in Next.js and the cases where each one pays off.
- motion
- scroll
The definitive guide — a Next.js site built around motion and scroll
The scroll foundation that, when missing, keeps the animations from working at all: Lenis, GSAP and Next.js wired in the right order and the mistakes to avoid.
- next.js
- lenis
Infra •
Documentation: deploying a Next.js application with GitHub + Hostinger
Every push becomes a live site with no hosting panel involved: connecting GitHub to Hostinger, the build settings that break and the checks after each deploy.
- deploy
- github


