Trending Topic
Claude Code extension primitives compared — skills, subagents, slash commands, hooks, and plugins mapped onto one decision framework
AI Tools for Developers

Claude Code Skills vs Subagents vs Slash Commands vs Hooks vs Plugins: The Decision Guide (2026)

Sumit Patel

Written by

Sumit Patel

Published

July 23, 2026

Updated

July 23, 2026

Reading Level

Advanced Strategy

Investment

26 min read

Quick Answer

Skills vs subagents vs commands vs hooks vs plugins — the short version

  • 1
    Skill → a folder with SKILL.md (plus optional files) that teaches Claude a reusable method. Invoked by you as /command-name, or auto-invoked when its description matches the task. Custom slash commands are now part of this system.
  • 2
    Slash command → today, mostly a synonym: old .claude/commands/*.md files still work, but new custom commands should be skills. Built-in commands (/help, /clear, /model, /compact) remain separate CLI features.
  • 3
    Subagent → a forked Claude with its own context window. Use for delegation, exploration, and anything parallel. Its context is lost when it finishes — that's the price of isolation.
  • 4
    Hook → a deterministic script at a lifecycle event (PreToolUse, PostToolUse, Stop...). Runs every time, no model judgment. Formatters, guards, test gates.
  • 5
    Plugin → a versioned bundle of all of the above plus MCP definitions. The distribution format, not a new kind of logic.
  • 6
    CLAUDE.md → ambient always-loaded rules. Keep it short; extract situational content into skills.
  • 7
    One-line rule → command the human triggers: skill. Behavior that must happen regardless: hook. Work to delegate or parallelize: subagent. Setup to share: plugin.

Why I'm the one writing this — and why most comparison posts need a correction.

I'm a frontend developer. I build a 25-module ERP plus client CRM projects in React and TypeScript, and Claude Code drives a large share of that work daily — which means I've lived through every stage of its extension system, including the stage where 'should this be a command or a skill?' was a genuine time-wasting dilemma with comparison tables that contradicted each other. Then Anthropic resolved the dilemma by dissolving it: custom slash commands were folded into the skills system, with full backwards compatibility. That's the right design decision — the two things were never meaningfully different — but it quietly obsoleted a large share of the comparison content that still ranks for these queries. If you've read a 'commands vs skills' guide that treats them as rival systems, you've read pre-merge documentation. This post is the current map: the five primitives as one decision framework, verified against the official docs at my current Claude Code version ([[FILL: your Claude Code version at time of writing (claude --version)]]), illustrated with my actual — deliberately small — setup rather than an aspirational one. Where my own usage is thin (I'll be honest about which primitives I barely touch), I say so instead of pretending. No affiliation with Anthropic, no affiliate links; Claude Code ships new versions constantly, so verify mechanics against code.claude.com/docs before you standardize a team on anything here.

Every Claude Code user hits the same wall around week two: you've repeated the same instructions enough times that you know you should automate them — and then you discover there are five different ways to do it, and every guide defines them in isolation. Skills. Subagents. Slash commands. Hooks. Plugins. Add CLAUDE.md and MCP servers to the pile and you have seven concepts fighting for one job in your head. The comparison posts don't help as much as they should, for a specific reason: many of them are already wrong. Custom slash commands were merged into the skills system — old command files still work, but the 'commands vs skills' debate those posts agonize over has been settled by Anthropic deleting the distinction. So this guide does two things the existing content doesn't. First, it gives you the post-merge taxonomy — what each primitive actually is in the current Claude Code, verified against the official docs rather than months-old blog posts. Second, and more useful, it replaces five definitions with one decision framework built on a single question: who triggers this work, and how much discretion should the model have about it? Answer that question and the primitive picks itself. Human triggers it explicitly: user-invoked skill. Model should apply it when relevant: auto-invoked skill. Must happen every time with no discretion: hook. Needs its own context or needs to run in parallel: subagent. Needs to be shared as a package: plugin. The rest of this article is that framework expanded — with the comparison table, my own real (and modest) setup as the running example, and the anti-patterns section covering the expensive mistakes: judgment in hooks, destructive workflows on auto-trigger, and one-off prompts promoted into skills they didn't earn.

Key Takeaways

8 Points
1
The taxonomy most comparison posts teach is outdated: custom slash commands were merged into the skills system (Claude Code v2.1.3). Old .claude/commands/ files still work, but skills — directories with a SKILL.md plus supporting files — are the recommended path, and a skill wins over a same-named command.
2
The framework that replaces five definitions is one question: who triggers it, and how much discretion should the model have? Human explicitly → user-invoked skill (/command). Model when relevant → auto-invoked skill (description matching). Every time, guaranteed, no discretion → hook. Delegated with isolated context or in parallel → subagent. Shared as a package → plugin.
3
Skills are context-efficient by design: progressive disclosure means only metadata is scanned per session, the SKILL.md body loads when the skill fires, and supporting resources load only when needed — unlike CLAUDE.md, which occupies context every session.
4
Subagents are the only primitive with parallel execution, and the only one with an isolated context window — the trade-off is that their context is discarded when they finish. See 'parallel' in a task description? That's a subagent.
5
Hooks run every time at lifecycle events (PreToolUse, PostToolUse, Stop and others) with zero model discretion — right for formatters, guards, and test runs; wrong for judgment calls like review taste.
6
Plugins are versioned bundles of skills, subagents, commands, hooks, and MCP definitions — the distribution layer, not a sixth kind of logic.
7
My own setup is deliberately small: [[FILL: how many skills/commands/hooks you actually have in your setup right now, and the 2-3 you use most]] — replace with your real setup before publishing.
8
Claude Code ships versions near-daily and behavior details shift with them — every mechanic here was verified against the official docs at the time of writing (Claude Code [[FILL: your Claude Code version at time of writing (claude --version)]]); check code.claude.com/docs before building team conventions on any of it.

The 30-Second Decision Framework

If you only read one section, read this one.

Stop asking 'what's the difference between X and Y' five times. Ask one question about the work itself: who should trigger it, and how much discretion should the model have?

If a human should explicitly start it — a release checklist, a PR-description generator, a refactor procedure — make it a skill and invoke it as /command-name. The explicit trigger is a feature: you get a deliberate, button-like moment for workflows that shouldn't fire on a model's guess.

If the model should apply it whenever relevant — 'how we write migrations in this repo,' 'our component conventions' — make it a skill with a good description and let auto-invocation do the work. Same primitive, different trigger setting.

If it must happen every single time, with zero discretion — format after every edit, block writes outside the repo, run the test suite when the session stops — that's a hook. Hooks don't ask the model; they fire at lifecycle events, deterministically.

If the work should be delegated with its own context, or needs to run in parallel — codebase exploration, an independent review pass, three research threads at once — that's a subagent: a forked Claude with an isolated context window. The keyword is literally 'parallel': nothing else in the system does it.

If you're packaging any of the above to share — with your team, or the community — that's a plugin: a versioned bundle of skills, subagents, commands, hooks, and MCP definitions.

Notice what's not in the framework: 'slash command' as a separate destination. That's the merge — commands are how you invoke skills now, not a rival system. The next section covers why, because it's the correction half the internet still needs.

First, the Merge: Slash Commands Became Skills (And Your Old Files Still Work)

This is the fact that dates every comparison post written about the old system, so let's get it exactly right.

Historically, Claude Code had two separate customization paths that did nearly the same thing. Slash commands lived in .claude/commands/ as single markdown files — create review.md, get /review. Skills lived in .claude/skills/ as directories containing a SKILL.md plus supporting files, designed for auto-discovery when the task matched their description. Both created invocable workflows. Both could be auto-triggered. Both loaded instructions into context. Developers burned real time deciding between them, and the honest answer was usually 'it barely matters.'

So Anthropic unified them: as of v2.1.3, custom slash commands are part of the skills system. The practical rules of the merged world:

One — backwards compatibility is real. Files in .claude/commands/ keep working unchanged; nothing breaks on update. In my own setup, [[FILL: whether your old .claude/commands/ files still work post-merge, and whether you migrated them to skills]].

Two — skills are the recommended path for anything new, because they carry features flat command files don't: a directory for supporting files (templates, examples, scripts), frontmatter controls like disable-model-invocation, user-invocable, and allowed-tools, and automatic invocation on description match.

Three — precedence: if a skill and a command share a name, the skill wins. .claude/commands/review.md and .claude/skills/review/SKILL.md both want to be /review; the skill gets it.

Four — the /command surface itself now has several sources: built-in CLI commands (/help, /clear, /model, /compact — hardcoded features, untouched by the merge), your skills, plugin-provided commands (namespaced by plugin), and MCP prompts. Same slash, four origins.

One genuinely useful newer mechanic worth knowing: skill stacking. Recent versions let you start a message with multiple skills — the first plus up to five more — and pass trailing text as arguments to each, so /code-review /fix-issue 123 loads both with 123 as the argument. Check /skills for what's available in your session; it lists built-ins and your own.

  • v2.1.3 merged custom slash commands into the skills system — the 'commands vs skills' debate is settled by design.
  • .claude/commands/*.md files still work, unchanged. Migration is optional, not urgent.
  • New custom commands should be skills: .claude/skills/name/SKILL.md, with supporting files and frontmatter controls.
  • Name conflict → the skill wins over the command.
  • The / prefix now surfaces four sources: built-in CLI commands, skills, plugin commands, MCP prompts.
  • Skill stacking: invoke multiple skills in one message (first plus up to five more), with trailing text passed as arguments to each.

Skills: The Playbook Primitive (And Why They're Cheap on Context)

A skill is a folder-based instruction pack: a directory under .claude/skills/ containing a SKILL.md — the method, written in markdown with optional YAML frontmatter — plus whatever supporting files the method needs: templates, examples, reference docs, even scripts. It turns a general agent into a specialist for one recurring job in your codebase.

The design detail that makes skills the workhorse primitive is progressive disclosure, and it's worth understanding because it's the answer to 'won't all these files bloat my context?' Skills load in three levels. Level one: only the name and description are scanned each session — a few lines per skill, nearly free. Level two: when a skill fires (you invoke it, or its description matches the task), the SKILL.md body loads. Level three: supporting resources load only if the work actually needs them. Compare that to pasting the same instructions into every conversation, or to a bloated CLAUDE.md that occupies context whether relevant or not, and you see why the pattern won.

The trigger is configurable per skill, which is where the decision framework from earlier becomes concrete frontmatter. Want it human-only — a deploy procedure that should never fire on a model's guess? Set disable-model-invocation: true. Want it model-discoverable — repo conventions Claude should apply whenever it touches the relevant code? Write a precise description and let matching work. The description field is doing real routing work either way: vague descriptions mean skills that fire at the wrong times or never.

From my own setup, the skill I use most: [[FILL: one real skill or command from your workflow, what it does, roughly how its file is structured]]. Nothing exotic — and that's representative. The best skills encode boring, repeated method: how this repo writes a Redux slice, what a PR description must contain, the checklist before touching the billing module.

When a skill is the wrong choice: when the work needs guaranteed execution (hook), when it needs isolated or parallel context (subagent), or when it's a rule that genuinely applies every session (CLAUDE.md — sparingly).

Subagents: Isolation and Parallelism (The Only Primitive That Forks)

A subagent is a forked Claude instance with its own context window. Your main session delegates a task to it; the subagent works in isolation; results come back; the subagent's context is discarded. Every property that matters about subagents follows from that shape.

Isolation is the headline benefit. Long agentic sessions die by context pollution — exploration transcripts, file dumps, dead ends accumulating until the model loses the plot. Delegating the noisy phases to a subagent keeps your main context clean: an exploration subagent can read thirty files and return a two-paragraph summary, and your session pays for the summary, not the thirty files. That's why 'use subagents to keep the main context small, especially for exploration and planning' has become standard advice.

Parallelism is the exclusive benefit. Subagents are the only primitive in this taxonomy that supports running work concurrently — the practical keyword rule holds: when a task description contains 'in parallel,' the answer is subagents, full stop. Nothing else forks.

The cost is symmetric with the benefit: the isolated context is lost when the subagent finishes. Whatever nuance it discovered and didn't put in its return summary is gone. That makes subagents wrong for work where accumulated context is the point — a long refactor where each step builds on the judgment of the last belongs in your main session, not scattered across amnesiac forks.

On my ERP codebase, the shape that earns subagents is [[FILL: one real situation where you used or would use a subagent on the ERP codebase]] — the pattern being: bounded question in, compact answer out, details safely forgettable.

One composition note that ties the system together: primitives stack. A skill can specify that its work runs as a subagent; a user-invoked skill can orchestrate a pipeline where a subagent explores, the main session implements, and a hook formats the result. The primitives are less five rival features than five roles in one workflow.

  • Subagent = forked Claude with an isolated context window; results return, context is discarded.
  • Use for: exploration, research, independent review passes — anything where the main session needs the answer, not the transcript.
  • The exclusive capability: parallel execution. 'In parallel' in a task description = subagents, always.
  • The cost: no context persistence. Work whose value is accumulated judgment stays in the main session.
  • Primitives compose: skills can delegate to subagents; hooks can wrap the results. Think roles in a pipeline, not rival features.

Hooks: The Guarantee Primitive (Determinism, Not Judgment)

Everything else in this taxonomy involves the model deciding something. Hooks are the opposite: deterministic scripts bound to lifecycle events, configured in settings.json or as scripts in your hooks directory, that fire every time the event occurs — no discretion, no description-matching, no model in the loop for the decision to run.

The lifecycle events are the vocabulary: PreToolUse fires before a tool call (and can block it — this is where 'never write outside the repo' guards live), PostToolUse fires after (the classic: run the formatter after every file edit), and Stop fires when Claude finishes (run the test suite, notify, lint the diff). The common production patterns are exactly the ones you'd guess: auto-format on edit, path and command guards, test gates on completion, secret redaction on shell commands.

The design principle that keeps hooks healthy is the one the best guides converge on: hooks are for certainty, skills are for method. A hook is excellent at 'this command pattern is forbidden' and terrible at 'is this code well-designed?' — deterministic checks, yes; broad review taste, no. If a check requires judgment, it belongs in a skill or subagent where the model can reason; forcing judgment into a hook gets you brittle regexes doing a reviewer's job badly.

The honest state of my own hook usage: [[FILL: one real hook you run (e.g. formatter after edits) — or an honest note that you don't use hooks yet and why]]. I'll flag the pattern I see in my own behavior and in readers': hooks are the most under-adopted primitive relative to their value, probably because they live in settings rather than in the conversational flow — you set them up once in cold blood rather than discovering them mid-task.

When a hook is the wrong choice: anything needing model judgment, and anything a human should consciously trigger. A hook that auto-deploys on Stop is not a productivity win; it's an incident report with a timestamp.

Plugins: The Shipping Box, Not a Sixth Logic

Plugins are the easiest primitive to place once you stop looking for new behavior in them: a plugin is a versioned bundle that packages skills, subagents, commands, hooks, and MCP server definitions together for installation as a unit. It's the distribution layer. Skills are playbooks, hooks are guarantees, subagents are delegates — plugins are the box they ship in.

What that means practically: when you install a plugin, you're installing a complete configured setup — its commands appear in your session namespaced by plugin (so a design plugin's command arrives as /plugin-name:command rather than colliding with yours), its hooks register, its skills become available. This is how whole workflows move between people: a team lead packages the repo's conventions, review skill, and formatting hooks once, and every developer installs one thing instead of copying five files into the right directories.

When to build one: the moment your setup needs to exist identically on a second machine or a second person. Before that moment, plugins are premature packaging — loose files in .claude/ are easier to iterate on. After it, they're the difference between 'here's my zip of dotfiles and a README' and versioned, updatable infrastructure. Teams should also treat plugin choice with mild security seriousness: a plugin can register hooks that run scripts on your lifecycle events, so 'install from people you trust' applies with the same force as any package manager.

My own usage is the honest baseline for how optional plugins are for a solo developer: my setup is [[FILL: how many skills/commands/hooks you actually have in your setup right now, and the 2-3 you use most]], and none of it is packaged as a plugin — because no second machine or teammate needs it yet. The day EdgeNRoots standardizes the ERP conventions across the team is the day that changes, and that's exactly the boundary the primitive is for.

The Five-Way Comparison Table

The framework, compressed into the table you'll actually screenshot. One deliberate editorial choice: 'slash command' gets a column so the table answers the query people search, but its column mostly points at skills — because that's the true post-merge answer.

Comparison Data
dimensionskillslash commandsubagenthookplugin
What it isFolder with SKILL.md + supporting files — a reusable methodPost-merge: how you invoke a skill. Old .claude/commands/ files still work; built-ins (/help, /clear) are separate CLI featuresForked Claude with its own context windowDeterministic script at a lifecycle eventVersioned bundle of skills + subagents + commands + hooks + MCP definitions
Who triggers itYou (/name) or the model (description match) — configurable per skillYou, explicitlyThe model (delegation) or a skill that specifies itThe lifecycle event — always, automaticallyN/A — it's packaging; its contents keep their own triggers
Model discretionYes — the model applies the method with judgmentYes, once invokedYes, in its own contextNone. That's the pointInherited from contents
Context behaviorProgressive disclosure: metadata always, body on trigger, resources on need — cheap until usedLoads the skill body into current context on invocationIsolated window; main session pays only for the returned summary; context lost afterRuns outside the conversation — effectively zero context costPer its contents
Parallel executionNoNo (can stack up to six skills in one invocation, but they run in-session)Yes — the only primitive that doesNo (fires per event)No (packaging)
Lives at.claude/skills/name/SKILL.md (project) or ~/.claude/skills/ (user)Legacy: .claude/commands/*.md — still honored; skill wins name conflictsDefined via agent configuration / invoked as a tasksettings.json or hooks scripts directoryInstalled from a marketplace or repo; commands namespaced by plugin
Best forRecurring method: conventions, checklists, procedures with templatesDeliberate human-triggered workflows (deploy, release, PR description)Exploration, research, review passes, anything parallelFormatters, guards, test gates, secret redaction — guaranteesSharing a complete setup with a team or the community
Wrong forOne-off prompts; rules that must run every timeAnything the model should discover on its ownWork whose value is accumulated context across stepsJudgment calls; anything destructive on auto-fireA solo setup nobody else installs — premature packaging

* Claude Code ships new versions near-daily, and mechanics in this table — stacking limits, frontmatter fields, precedence rules — are version-dependent. Everything here was verified against the official documentation at code.claude.com/docs at the time of writing (Claude Code [[FILL: your Claude Code version at time of writing (claude --version)]]). Re-verify before standardizing a team convention on any row.

Where CLAUDE.md and MCP Fit (The Two Adjacent Pieces)

Two things sit next to this taxonomy and get wrongly merged into it, so let's place them precisely.

CLAUDE.md is the ambient layer: a markdown file read at the start of every session, encoding persistent instructions — project conventions, commands to run, hard constraints. Its defining property is also its cost: it occupies context all the time, relevant or not. That yields a clean division of labor with skills. Rules that genuinely apply to every session — 'this repo uses pnpm,' 'never touch the generated folder' — earn their permanent context residence in CLAUDE.md. Anything situational — the migration procedure, the release checklist, the PR format — belongs in a skill, where progressive disclosure makes it free until needed. The practical audit: read your CLAUDE.md and ask, per paragraph, 'does this apply to every single session?' The paragraphs that answer 'only sometimes' are skills waiting to be extracted, and extracting them is the cheapest context optimization available.

MCP servers are the capability layer: they connect Claude to external systems — databases, browsers, issue trackers, design tools — giving it tools it doesn't natively have. The clean distinction from skills: MCP provides abilities, skills provide method. An MCP server lets Claude query your Postgres; a skill teaches it how your team writes reporting queries against that Postgres. They compose rather than compete — a skill can direct MCP tool use, and plugins can bundle MCP definitions alongside everything else. One operational contrast worth knowing: traditional MCP servers load their tool definitions up front, which historically made heavy MCP setups context-expensive at session start — one more reason the skills pattern, with its lazy loading, took over so much of the customization surface. I covered the setup side in my MCP servers guide; this taxonomy is the 'when to reach for which' layer above it.

With those two placed, the full stack reads cleanly: CLAUDE.md for always-true context, skills for on-demand method, hooks for guarantees, subagents for delegation, MCP for external capability, plugins for shipping the lot.

  • CLAUDE.md = ambient rules, paid for in context every session. Reserve for genuinely always-true instructions.
  • The audit: any CLAUDE.md paragraph that applies 'only sometimes' should be extracted into a skill.
  • MCP = external capability (tools); skills = method for using capability. They compose, not compete.
  • MCP tool definitions historically load up front (context-heavy); skills load progressively (context-cheap) — a key reason skills became the default customization surface.
  • Full stack in one line: CLAUDE.md (context) → skills (method) → hooks (guarantees) → subagents (delegation) → MCP (capability) → plugins (distribution).

Anti-Patterns: The Four Expensive Mistakes

The framework tells you what to build. Experience — mine and the community's — says these four things not to build cost the most.

One: judgment in hooks. Hooks excel at deterministic checks — block that path, run that formatter — and fail at taste. A hook trying to enforce 'good code review' via pattern matching is a brittle regex doing a reviewer's job; the review belongs in a skill or subagent where the model can actually reason. If writing the hook script has you encoding opinions rather than rules, you're in the wrong primitive.

Two: destructive workflows on auto-trigger. Anything that can deploy, publish, delete, spend money, or touch production should keep a deliberate human invocation — a user-invoked skill with disable-model-invocation set, never an auto-matched skill or a Stop hook. The convenience delta of auto-triggering a deploy is seconds; the failure mode is production. Package the method as a skill by all means; keep the trigger in human hands.

Three: one-off prompts promoted to skills. A skill earns its directory when a workflow repeats and benefits from structure — templates, references, checklists. A prompt you liked once is not a skill; it's a note. Promoting every good prompt creates a skills directory full of vague descriptions that misfire on auto-invocation and bury the five skills that matter. My own bar, stated earlier: third repetition, or it stays a note.

Four: collecting primitives as strategy. Knowing many commands, installing many plugins, defining subagents you never delegate to — surface area isn't capability. The developers getting real leverage from this system run small, sharp setups where every piece answers the who-triggers-it question crisply. Mine is deliberately minimal, and the honest inventory is in the sections above; I'd rather ship that than an impressive-looking .claude/ directory I don't use.

The meta-pattern across all four: every mistake is a trigger mismatch — model discretion where determinism belonged, automation where deliberation belonged, permanence where a one-off belonged. Which is the framework's final argument for itself: get the trigger right and the rest of the decision collapses.

Frequently Asked Questions

As of v2.1.3, custom slash commands are part of the skills system — no longer separate primitives. A skill (a directory under .claude/skills/ with a SKILL.md plus supporting files) creates a /command-name exactly like old .claude/commands/*.md files did. Old command files still work; skills are recommended because they add supporting files, frontmatter controls (disable-model-invocation, user-invocable, allowed-tools), and auto-invocation on description match. On a name conflict, the skill wins. Built-in CLI commands like /help and /compact are a separate, unchanged category.
When you need context isolation or parallelism. A subagent is a forked Claude with its own context window — ideal for exploration, research, and review passes where your main session needs the answer, not the transcript, and it's the only primitive that runs work in parallel. The trade-off: its context is discarded when it finishes. Skill = teach the current session a method; subagent = delegate work whose details you don't need to keep.
Guarantees. Hooks are deterministic scripts bound to lifecycle events — PreToolUse (can block tool calls), PostToolUse (e.g. run a formatter after every edit), Stop (e.g. run tests when Claude finishes) — configured in settings.json or your hooks directory. They fire every time with no model discretion, which makes them right for formatters, path guards, test gates, and secret redaction, and wrong for judgment-heavy work like review quality, which belongs in a skill or subagent.
The distribution layer: a versioned bundle that packages skills, subagents, commands, hooks, and MCP server definitions for installation as a unit. Install one and you get a complete configured workflow — commands arrive namespaced by plugin name to avoid collisions. Build one when your setup needs to exist identically on a second machine or for a teammate; before that, loose files iterate faster.
CLAUDE.md for rules that apply to literally every session (package manager, hard constraints, conventions) — it loads at session start and occupies context permanently. Skills for anything situational (checklists, procedures, formats) — progressive disclosure means they cost near-zero context until triggered. The audit: any CLAUDE.md paragraph that applies 'only sometimes' should be extracted into a skill.
Yes — the merge was fully backwards-compatible, and .claude/commands/*.md files keep creating their /command-name entries. New custom commands should go in .claude/skills/ as directories with a SKILL.md, and if a skill and command share a name, the skill takes precedence. Migrate when you want supporting files, frontmatter controls, or auto-invocation — not because anything will break if you don't.

Strategic Summary

Final Thoughts

The honest summary: Claude Code doesn't have five competing features. It has one extension system with five roles, and the confusion mostly comes from documentation written before the roles settled — especially before custom slash commands were merged into skills, a change that quietly retired half the comparison content still ranking for these queries. The framework that survives contact with real work fits in four lines. Skill: a method, triggered by you or discovered by the model. Hook: a guarantee, fired by lifecycle events with no discretion. Subagent: a delegate with its own disposable context — and the only route to parallelism. Plugin: the box you ship the other three in. CLAUDE.md holds the always-true context underneath; MCP supplies external capability alongside. My parting advice mirrors my own deliberately small setup: build less than you think. One skill at the third repetition of a method. One hook for the thing you keep reminding the model to do. A subagent when the transcript would pollute your session or the work can genuinely fork. A plugin the day a second person needs your setup. Every primitive added past need is context, maintenance, and misfire surface — the developers winning with this system run sharp little toolkits, not museums. And because Claude Code ships versions near-daily: the mechanics here were verified against the official docs at my version on the publish date, and the framework will outlive the details — but check code.claude.com/docs before you standardize a team on any specific behavior. When the taxonomy shifts again, this post will get the same correction treatment I just gave everyone else's. --- Last reviewed: July 2026. Mechanics — the commands-into-skills merge, precedence rules, frontmatter fields, stacking limits, hook events, plugin composition — are taken from official Claude Code documentation (code.claude.com/docs) and version-release coverage at the time of writing, at Claude Code [[FILL: your Claude Code version at time of writing (claude --version)]]. Claude Code updates near-daily; verify against current docs before relying on version-specific behavior. Setup examples reflect my own real configuration. No affiliation with Anthropic; no affiliate links.

What does your .claude/ directory actually look like — how many skills, hooks, and subagent definitions, and which three earn their place? Tell me in the comments. I'm collecting real setup inventories across solo devs and teams, and early signs say the median winning setup is much smaller than the tutorials imply.

If you found this useful, I write hands-on, no-hype guides to Claude Code's moving parts — extension primitives, MCP setup, usage limits — from daily use in real client work. Browse the AI Tools for Developers hub, or reach me via stacknovahq.com/contact.

Next Up

Continue your research