The Interview Edge Blog
← Back to all guides
Claude · Skills, subagents, hooks

Skills vs Subagents vs Hooks: Three Claude Code Features, Three Different Jobs

They’re the three words everyone mixes up — and they solve three different problems. The docs’ own definitions, a one-sentence decision rule for which one you need, how the three compose, and starter files you can copy into your own .claude folder today.

Explain it like I’m five

Imagine a really capable assistant who can do anything — but forgets everything between visits. A skill is a written recipe you leave on their desk: “when you summarize my changes, always check for secrets.” They follow it whenever it’s relevant. A subagent is when you clone that assistant for one specific job — a fresh brain that goes off, does the deep research, and comes back with just the answer. A hook is a tripwire you install in the hallway: every time anyone walks past with scissors, the tripwire stops them — automatically, no asking, no exceptions.

Skill = knowledge the assistant carries. Subagent = a fresh worker you launch. Hook = a rule that always runs. Confusing them is the norm — this guide un-mixes them for good.

The decision rule

The fastest way to pick the right one: describe what you want in one sentence, and the shape of the sentence gives you the answer.

→ skill

“I repeat the same instructions every session.” A checklist, a procedure, a way-of-working you keep pasting into chat — that knowledge belongs in a reusable playbook Claude can reach for on its own.

→ subagent

“This task deserves its own clean brain.” A deep dive, an investigation, a parallel chunk of work — something that benefits from a fresh context window, its own instructions, and its own permissions.

→ hook

“This must happen every time, no exceptions.” A guardrail, a check, a side effect that should never be skipped or forgotten — enforcement that fires automatically at a specific moment.

Daily-work version: skills hold your team’s checklists, subagents do the deep dives, hooks enforce the rules. Memorize that sentence.

The trap

None of the three is a superset of the others. A hook can’t carry team knowledge, a skill can’t guarantee it always runs, and a subagent can’t do anything without instructions. Pick by the job, not by the hype.

Skills: reusable playbooks

Skills are the answer to “I keep pasting the same instructions.” Write the procedure once; Claude carries it.

The official definition is admirably plain: “Skills extend what Claude can do. Create a SKILL.md file with instructions, and Claude adds it to its toolkit. Claude uses skills when relevant, or you can invoke one directly with /skill-name.” Unlike CLAUDE.md content, a skill’s body loads only when it’s used — so long reference material costs almost nothing until you need it.

The docs’ own starter example is a summarize-changes skill: it pulls your live git diff into the prompt, summarizes your uncommitted changes, and flags anything risky. Claude loads it automatically when you ask about your changes — or you invoke it directly with /summarize-changes.

Where a skill lives

Location decides scope. Save the skill at .claude/skills/<skill-name>/SKILL.md in your repository and it loads for sessions in that repo — commit it and your whole team gets it. Personal skills go under ~/.claude/skills/ for every project on your machine. A skill is configured with YAML frontmatter at the top of SKILL.md — only description is required in practice, so Claude knows when to reach for it — followed by the markdown instructions. A minimal starter is in the Starter files section below.

Source: Skills — Claude Code docs ↗

Subagents: specialists on demand

Subagents are the answer to “this job deserves its own clean brain.” Launch a specialist; get back just the result.

Again, the docs’ own words: “Subagents are specialized AI assistants that handle specific types of tasks… Each subagent runs in its own context window with a custom system prompt, specific tool access, and independent permissions.” That “own context window” clause is the load-bearing detail — the subagent never saw your main chat’s reasoning, so it can’t be charmed by it, and whatever noise it wades through never floods your conversation.

The concrete example: the built-in Explore agent. Point it at a question about your codebase and it searches everything — fast, read-only — then returns only the summary. The noise stays in its window; your chat gets the answer. (It’s the same “fresh eyes” mechanic that makes a reviewer catch what a writer misses, as we covered in the ECC teardown.)

Custom subagents are defined the same way skills are — a markdown file with frontmatter, living in .claude/agents/ — with their own system prompt, tool permissions, and optionally their own model. They’re how you turn a recurring deep dive into a one-line launch.

Source: Subagents — Claude Code docs ↗

Hooks: automatic tripwires

Hooks are the answer to “this must happen every time.” Define the rule once; it fires at a specific moment, forever.

The official definition: “Hooks are user-defined shell commands, HTTP endpoints, MCP tool calls, LLM prompts, or subagents that execute automatically at specific points in Claude Code’s lifecycle.” The lifecycle events include per-session (SessionStart, SessionEnd), per-turn (UserPromptSubmit, Stop), and on every tool call (PreToolUse, PostToolUse) — the last of which can block the tool call before it executes.

The docs’ own walkthrough is the canonical example: a PreToolUse hook on the Bash tool that inspects every shell command before it runs. The hook script reads the tool call’s JSON from stdin, extracts the command, and returns a permissionDecision of deny if it contains rm -rf — so the destructive command never executes, no matter how distracted Claude is. That’s a hook doing the one thing only a hook can do: enforcing a rule with zero reliance on anyone remembering it.

Security caution

Hooks run automatically with your permissions — shell commands that fire on events you don’t directly trigger. Treat a hook like a dependency: read the script it executes before installing it, understand exactly which events it fires on, and prefer the most narrowly scoped matcher that does the job. The tripwire protects you from Claude’s mistakes; a malicious tripwire is worse than none at all.

Source: Hooks — Claude Code docs ↗

How they compose

The three aren’t alternatives — they’re layers, and they nest. Here’s the composition the docs support.

Hook → subagent

Hook handlers can themselves be subagents (agent hooks): the hook fires on an event, and the subagent it spawns uses tools like Read, Grep, and Glob to verify conditions before returning a decision. The tripwire can dispatch an investigator.

Subagent → skill

A skill can run in its own subagent context (the docs’ context: fork frontmatter field), and subagents can load skills just like the main session can. The specialist arrives with the playbook already in hand.

Skill → hook

Skills can declare their own hooks in their frontmatter, which run for the rest of the session once the skill is invoked. And in reverse: hooks run inside subagents too, so the rules still hold wherever the work happens.

Picture the full chain: a PreToolUse hook inspects a risky command — instead of just blocking it, it fires a subagent to investigate, and the subagent loads the security-review skill to judge it. Hook blocks, subagent investigates, skill tells it how.

Starter files: copy these today

Two minimal files, verified against the official docs. Drop them in your project and you’ll have one skill and one hook running.

Starter 1: a SKILL.md skeleton

Shape verified from the docs: YAML frontmatter between --- markers at the very top of the file (name sets the command name, description tells Claude when to reach for it), then markdown instructions below. The ! line is dynamic context injection — the docs’ Claude Code extension that runs the command and pulls live output into the prompt.

markdown · .claude/skills/summarize-changes/SKILL.md
---
name: summarize-changes
description: Summarize uncommitted git changes and flag anything risky. Use when asked about current changes or before committing.
---

# Summarize Changes

!`git status --short && git diff --stat`

1. Read the live diff above — ground everything in it, not in guesses.
2. Group changes by intent: feature, fix, refactor, config.
3. Flag anything risky: secrets, migrations without a rollback plan,
   untested paths, large generated-file churn.
4. End with a one-line verdict: safe to commit, needs review, or stop.

Invoke with /summarize-changes, or ask Claude about your changes
and let it load automatically.

Starter 2: a PreToolUse hooks config

Shape verified from the docs: hooks live in a JSON settings file (project scope: .claude/settings.json) with three levels of nesting — the event (PreToolUse), a matcher group narrowing it to the Bash tool, and the handler (type "command", with an if rule in permission-rule syntax). The script reads the tool call’s JSON on stdin and returns "deny" when the command contains rm -rf — that’s the docs’ own walkthrough behavior, so the script below only needs to do that one job. Make it executable: chmod +x .claude/hooks/block-rm.sh.

json · .claude/settings.json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "if": "Bash(rm *)",
            "command": ".claude/hooks/block-rm.sh"
          }
        ]
      }
    ]
  }
}

FAQ

FAQ
I keep pasting the same checklist into chat. Which one fixes that?

A skill. That’s the docs’ own trigger condition: “Create a skill when you keep pasting the same instructions, checklist, or multi-step procedure into chat, or when a section of CLAUDE.md has grown into a procedure rather than a fact.” The skill loads its body only when used, so it stops costing you context on every turn.

FAQ
Can a skill guarantee it always runs?

No — and that’s exactly why hooks exist. Claude decides when a skill is relevant (or you invoke it manually). If the behavior must happen every single time with no exceptions — like blocking destructive commands — you need a hook, because hooks fire on lifecycle events whether or not anyone remembers them.

FAQ
Why not just make everything a subagent?

Because a subagent is a worker, not knowledge. It’s heavyweight: a fresh context window, its own system prompt, its own permissions — great for a deep dive, wasteful for a checklist. Skills give any agent the knowledge cheaply; subagents give the work a clean brain. They’re complements.

FAQ
Can a hook do the work of a skill?

Only sideways. A hook runs a fixed handler on an event — a shell command, an MCP tool call, an LLM prompt, or a subagent. It’s enforcement and automation, not a playbook Claude reasons over. If what you want is “Claude knows our deployment procedure,” that’s a skill; if what you want is “run the linter after every Write,” that’s a hook.

FAQ
Are hooks safe to install from other people?

Careful — the caution above applies in full. A hook is a shell command that executes automatically at lifecycle points, with your permissions. It can read stdin JSON containing your tool calls. Before installing anyone’s hook: read the script it executes, check which events and matchers it registers (narrow is better), and prefer hooks from authors you trust. The same rule we give for skills applies here — treat it like adding a dependency.

FAQ
Where should I start if I’ve never used any of them?

Start with one skill — take the most-pasted checklist in your workflow and turn it into a SKILL.md (the starter above takes five minutes). Next, add one subagent for the deep dive you do most often, like exploring unfamiliar code. Add a hook only when you’ve felt the pain of something being skipped: the rm -rf guard is the classic first hook because the pain it prevents is vivid.

Key takeaways

  1. Skill = reusable playbook: a SKILL.md with instructions, loaded when relevant or invoked with /skill-name. For repeated instructions and checklists.
  2. Subagent = specialist with a clean brain: its own context window, custom system prompt, tool access, and permissions. For deep dives and parallel work.
  3. Hook = automatic tripwire: a shell command (or endpoint, MCP call, prompt, or subagent) that fires at a specific lifecycle event — PreToolUse can block a tool call before it runs. For things that must happen every time, no exceptions.
  4. The decision rule: repeated instructions → skill; clean brain → subagent; must always run → hook.
  5. They compose: a hook can fire a subagent, a subagent can load a skill, and skills can declare their own hooks.
  6. Security posture: skills and hooks both run with your permissions — review the source of anything you install from others before trusting it.
Read nextECC Teardown: The Agent Harness That Won Anthropic’s Hackathon →