Claude Code extensibility gives you four distinct mechanisms to reshape the agentic coding workflow around your team’s needs. Skills, Hooks, Subagents, and Plugins each occupy a unique position on the extensibility spectrum, and choosing the wrong one wastes time, tokens, and context. This guide gives you a decision framework so you pick correctly the first time, every time.

Extensibility: What You’ll Learn
Claude Code ships with four extensibility mechanisms, and the hardest part is not learning each one in isolation. The real challenge is knowing which mechanism to reach for when a new requirement lands on your desk. This guide maps the full extensibility surface and gives you a repeatable decision process grounded in how Anthropic designed these tools to interact.
The Four Pillars of Claude Code Extensibility
Before you can choose between extensibility tools, you need a mental model of what each one actually does. The four pillars operate at different layers of the agentic loop. Skills inject knowledge, hooks inject determinism, subagents inject context isolation, and plugins inject distribution. Each extensibility mechanism has a distinct interface, lifecycle, and cost profile that determines where it fits.
Skills: Teachable Procedures
Skills are the most approachable extensibility mechanism. They are markdown instruction files stored in .claude/skills/ with a SKILL.md entry point. They use progressive disclosure to keep your context lean and your session fast. At session start, Claude loads only the skill name and description, roughly fifty tokens of overhead.
The full skill body, typically around five hundred tokens, loads only when Claude invokes the skill. Invocation happens either by auto-matching the skill description to your current task or through an explicit slash command like /deploy-checklist. Once loaded, the body stays in context for the rest of the session, giving Claude a persistent reference for that procedure.
Skills treat their instructions as advisory rather than deterministic. The model can drift from them when its judgment suggests a different path. This makes skills ideal for encoding conventions, deployment runbooks, and coding standards where flexibility matters. Skills also follow the open Agent Skills standard, making them portable across Cursor, Codex, and Cline. For the full deep dive, read the Claude Code Skills guide.
You reach for a skill when you keep pasting the same instructions into session after session, or when a section of CLAUDE.md has outgrown its role as a memory note and become a full procedure. Here is a minimal skill file demonstrating the frontmatter and body structure:
---
name: deploy-checklist
description: Guides safe production deployments step by step
---
# Deployment Checklist
1. Run the full test suite and confirm zero failures
2. Verify the staging build is green and deployable
3. Confirm the database migration is reversible
4. Tag the release commit in git with a semantic version
5. Post the changelog summary to the release channelNotice the structure: frontmatter for metadata that Claude reads at session start, then a markdown body with the actual procedure. The description field is what Claude uses for auto-matching, so it must clearly state what problem the skill solves. A vague description means the skill never triggers when it should, and a misleading one means it triggers when it should not. Getting the description right is half the battle in skill-based extensibility.
You can also scope skills to specific file paths or project types. A skill that encodes React component conventions should activate only when you are working in a React project, not when you are editing a Python backend file. Path scoping keeps irrelevant skills from loading and wasting context tokens. This is one of the most important extensibility optimizations for teams working across multiple stacks in a monorepo.
Hooks: Deterministic Enforcement
Hooks are the extensibility mechanism for things that must happen every single time, with zero room for model judgment. They are user-defined commands, HTTP endpoints, or LLM prompts that fire on specific lifecycle events such as PreToolUse, PostToolUse, SessionStart, and Stop. You configure them in settings.json.
The critical distinction is that the model has zero awareness that hooks exist. Claude cannot see them, cannot opt out of them, and cannot skip them. A hook fires deterministically when its matching event occurs, period. This makes hooks the gold standard for enforcement: running a linter after every edit, blocking dangerous commands like rm -rf, or posting a Slack notification when a session completes.
Hooks support five handler types. The command type runs a shell command. The http type sends a POST request to an endpoint. The mcp_tool type calls an MCP tool. The prompt type runs a single-turn LLM call for yes-or-no decisions. The agent type spawns a subagent, though this remains experimental. For comprehensive coverage, see the Claude Code Hooks guide.
Here is a PostToolUse hook that auto-formats files after every edit or write operation. This is one of the most common extensibility patterns teams adopt first:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "npx prettier --write $CLAUDE_FILE_PATH"
}
]
}
]
}
}The matcher field uses a pipe-separated list of tool names. In this example, the hook fires after any Edit or Write call. You can also use PreToolUse hooks to intercept actions before they happen and block them entirely. A PreToolUse hook that matches the Bash tool can inspect the proposed command and return a deny decision for anything matching rm -rf or git push --force. This is the extensibility mechanism for safety guardrails that protect against destructive operations.
Hooks can also chain together. You might have a PostToolUse hook that runs the linter, followed by another that runs the type checker, followed by a third that posts a notification. Each hook runs in sequence, and the model has no awareness of any of them. This invisible, deterministic chaining is what makes hooks the backbone of reliable extensibility enforcement in Claude Code.
Subagents: Isolated Context Workers
Subagents are the extensibility mechanism for context isolation. They are markdown files in .claude/agents/ that define isolated assistants with their own fresh context window. When the main session calls a subagent via the Agent tool, that subagent runs in a completely separate context. Only the final summary message returns to your main session.
This isolation is the killer feature. If you need to scan five hundred files for a security vulnerability, doing that inline would flood your context with intermediate results, file contents, and search noise. A subagent does all that work in its own context and returns a clean summary. Your main session stays focused on the task at hand.
Subagents can route to cheaper models via the model frontmatter field. A subagent running on Haiku costs a fraction of one on Sonnet, and for many tasks like log analysis or dependency audits, Haiku is more than sufficient. Subagents can preload skills, scope their own MCP servers, and nest up to five levels deep. The built-in options include Explore for read-only search and Plan for research. Learn more in the Claude Code Subagents guide.
Here is a subagent definition that audits dependencies. Note the model routing to Haiku for cost efficiency and the scoped tool access:
---
name: dependency-auditor
description: Audits project dependencies for vulnerabilities and license issues
model: haiku
tools: Read, Grep, Glob
---
You are a dependency auditor. Scan package files for
outdated or vulnerable packages. Return a concise
summary of findings with severity levels and
recommended actions.The built-in subagents cover common extensibility needs out of the box. Explore is a read-only search agent that scans your codebase without modifying anything, perfect for answering questions like where a function is defined or how many files reference a particular import. Plan is a research agent that investigates a problem space and returns a structured plan without writing any code. Both run in isolation and return summaries, keeping your main context clean.
Subagents can also nest. A main session can spawn a subagent, which in turn spawns its own subagent, up to five levels deep. This nesting is useful for complex extensibility workflows where one agent delegates subtasks to specialized workers. For example, a security review agent might spawn a dependency auditor and a code pattern scanner as subtasks, collect both summaries, and return a unified security report. The isolation compounds at each level, protecting your main context from exponential noise.
Plugins: Distribution and Packaging
Plugins are not a fourth peer primitive. They are a packaging and distribution layer that bundles any combination of skills, hooks, subagents, and MCP servers into a single installable unit. This is the most important conceptual point in the entire extensibility landscape, and getting it wrong leads to confused architectures.
A plugin uses a .claude-plugin/plugin.json manifest to declare what it bundles. You install plugins via a marketplace, a git URL, or the /plugin install command. The plugin adds zero new capability. Every primitive inside it, whether a skill or a hook or an agent, already works standalone. The plugin’s value is distribution: one-command install, versioning, and coherent sharing.
Think of it this way. You first decide which primitives you need, using the decision axes we cover next. Then, once those primitives are proven and stable, you optionally wrap them in a plugin for distribution. Plugins are orthogonal to the three core primitives. For the complete reference on manifests, marketplaces, and installation, read the Claude Code Plugins guide.
Here is a minimal plugin.json manifest that bundles a skill, an agent, hooks, and an MCP server into one distributable unit:
{
"name": "team-workflow",
"version": "1.0.0",
"description": "Team coding standards and automation",
"skills": ["skills/deploy-checklist"],
"agents": ["agents/dependency-auditor"],
"hooks": "hooks/hooks.json",
"mcpServers": "mcp/.mcp.json"
}The marketplace model is straightforward. You publish your plugin to a git repository, and anyone with the URL can install it with /plugin install. For internal team use, you can publish to a private marketplace that requires authentication. Versioning follows semantic versioning conventions, so breaking changes to hooks or skill descriptions trigger a major version bump. This ensures that teams can pin to a specific version and upgrade deliberately rather than being surprised by changes.
One common question is whether a plugin changes how the bundled primitives behave. The answer is no. A skill inside a plugin loads the same way as a skill in .claude/skills/. A hook inside a plugin fires the same way as a hook in settings.json. The plugin is transparent to the runtime. Its only effect is on distribution and installation, not on behavior. This transparency is what makes plugins safe to adopt: you never lose capability by moving a primitive into a plugin, and you never gain capability by taking it out.
The Extensibility Decision Framework
Now that you understand the four pillars, the question becomes: which one do you reach for? Anthropic frames the extensibility decision around four axes. Run your requirement through each axis in order, and the answer emerges clearly. The one-line summary that captures the entire framework is this: Skills teach, Subagents isolate, Hooks enforce, Plugins distribute.
Axis One: Determinism
The first question to ask is whether your requirement must fire every single time with zero model judgment involved. If the answer is yes, you need a hook or a permission rule. Hooks are deterministic by design. The model cannot see them, cannot skip them, and cannot override them. A PostToolUse hook that runs a linter after every edit will run after every edit, whether Claude feels like it or not.
Skills, by contrast, are advisory. Claude reads the skill body and generally follows it, but the model retains the discretion to deviate when it judges that a different approach is better. For enforcement tasks, that discretion is a bug, not a feature. For procedural guidance, that discretion is valuable because it lets Claude adapt to edge cases the skill author did not anticipate.
Axis Two: Context Isolation
The second question is whether your task would clutter your main context with noisy intermediate results. If the answer is yes, you need a subagent. Subagents run in their own fresh context window, do all their work there, and return only a summary to your main session. This is the right extensibility pattern for deep searches, log analysis, dependency audits, and any task that involves processing large volumes of information.
Without a subagent, those intermediate results pile up in your context window and crowd out the information you actually need. A dependency scan that reads fifty package.json files and three hundred lockfile entries would burn thousands of tokens if done inline. A subagent absorbs all that noise and hands back a tidy summary.
Axis Three: Trigger Model
The third question is whether your requirement is a reusable procedure or workflow that should activate when relevant. If the answer is yes, you need a skill. Skills auto-match their description to the current task and load their full body only when the match triggers. They play out inline in the main thread, meaning Claude can interact with you while following the skill, ask clarifying questions, and adapt steps to your specific situation.
This inline, user-steerable quality is what distinguishes skills from hooks. A hook fires and runs to completion without interaction. A skill guides Claude through a procedure while you remain in the loop. If your task needs judgment at each step, a skill is the right extensibility tool. If it needs zero judgment, a hook is better.
Axis Four: Distribution
The fourth question is whether you need to share your extensibility setup with a team or community. If the answer is yes, you wrap your primitives in a plugin. Plugins are the distribution layer, orthogonal to the three core primitives. They bundle skills, hooks, subagents, and MCP servers into one installable unit with versioning and one-command setup.
The critical insight is that plugins come last in the decision chain. You pick your primitives first, using axes one through three. Then, once those primitives are proven and stable, you decide whether packaging them as a plugin adds distribution value. Plugins never replace the decision about which primitive to use. They only solve the problem of how to share what you have built.
Extensibility Tools Compared
The comparison table below distills the key dimensions of each extensibility mechanism into a single reference. Use it as a quick-lookup guide when a new requirement lands and you need to narrow the field fast. Each row represents a decision-relevant property, and each column shows how the mechanism behaves on that property.
| Dimension | Skills | Hooks | Subagents | Plugins |
|---|---|---|---|---|
| Trigger model | Auto-matched to task or invoked via slash command | Lifecycle event fires the hook automatically | Explicit call through the Agent tool | Install command loads the bundled primitives |
| Persistence | Session-long once the body is loaded | Every matching event in every session | Single invocation, fresh context each time | Persists bundle definition across sessions |
| Context cost | Roughly 500 tokens when invoked | Zero tokens, runs outside the model | Only the summary returns, about 200 tokens | Zero tokens, it is only a container |
| Determinism | Advisory, the model can drift from instructions | Absolute, no model judgment involved at all | Advisory, the model decides what to summarize | Not applicable, packaging only |
| Statefulness | Stateless, re-read each new session | Stateless, driven by static config | Stateless, fresh context every call | Stateless, driven by the manifest file |
| Authority | Guides but cannot force specific actions | Can block, modify, or allow any tool action | Returns suggestions to the main thread | Inherits authority of bundled primitives |
| Sharing mechanism | Copy the skills folder into the repo | Share a settings dot json snippet | Copy the agents folder into the repo | Marketplace, git URL, or slash command install |
| Best for | Procedures, conventions, team checklists | Enforcement, automation, safety guardrails | Deep search, audits, context-heavy analysis | Team-wide distribution of proven primitives |
| Avoid when | You need guaranteed execution every time | The task requires judgment or iteration | The result needs iterative back-and-forth | Primitives are not proven standalone yet |
One critical note on reading this table: Plugins are orthogonal. They do not compete with the other three mechanisms. You choose your primitive first, then decide whether to package it as a plugin. Plugins add distribution value, not capability. A skill works identically whether it lives in .claude/skills/ directly or inside an installed plugin. The extensibility decision for capability always runs through skills, hooks, or subagents.
The Context Economy of Extensibility
Every extensibility mechanism has a context cost, and understanding that cost is essential for building efficient workflows. Context window space is finite. Every token spent on instructions, tool results, and intermediate data is a token not available for reasoning about your actual problem. The four mechanisms interact with context very differently, and choosing wisely can double your effective context budget.
Hooks have the lowest context cost: zero. They run entirely outside the model. A PostToolUse hook that formats your code consumes no context tokens at all. The model never sees the hook, never reads its output, and never spends tokens reasoning about it. For any task that can be expressed as a deterministic shell command or HTTP call, hooks are the clear winner on cost alone.
Subagents have the next lowest cost. When a subagent does its work, all the intermediate results, file reads, and search output stay in the subagent’s context. Only the final summary returns to your main session. That summary is typically two to three hundred tokens, regardless of how much work the subagent did. A dependency audit that reads three hundred files might cost the subagent twenty thousand tokens internally, but your main session only pays for the summary.
Skills cost roughly five hundred tokens when loaded, which happens once per session per skill invoked. That cost is permanent for the rest of the session. If you invoke three skills, you spend fifteen hundred tokens permanently. This is still far cheaper than pasting the same instructions manually, which might cost two thousand tokens each time you paste them, and the skill approach gives you structured, scoped activation.
The most expensive approach is putting everything in CLAUDE.md. Every instruction in that file loads at session start and stays forever. A bloated CLAUDE.md with ten procedures might cost five thousand tokens that you never get back, even if nine of those procedures are irrelevant to the current task. This is why extracting procedures into skills is one of the highest-leverage extensibility moves you can make.
You can measure the impact directly. Start a session and ask Claude to report its current context usage. Then invoke a skill, trigger a subagent, or fire a hook, and check again. The numbers tell the story clearly. Hooks add zero. Subagents add only their summary. Skills add their body once. CLAUDE.md adds everything permanently. This empirical approach to measuring extensibility cost helps you make data-driven decisions about where to invest your context budget, rather than guessing based on intuition.
Three Real-World Decisions, Worked Through
The comparison table gives you the map, but real decisions involve trade-offs that a table cannot capture. The three scenarios below walk through the full reasoning process, including why the chosen mechanism wins and why the alternatives fall short. Each scenario represents one of the most common extensibility questions teams face.
Decision One: Auto-Format Code After Every Edit
You want Prettier to run after every file edit, every time, without exception. The requirement is absolute determinism. If even one edit slips through unformatted, you get inconsistent diffs and review noise. Walking through the decision axes, axis one asks whether this must fire every time with zero model judgment. The answer is an unambiguous yes.
That points directly to a PostToolUse hook. The hook fires after every Edit or Write tool call, runs npx prettier --write on the affected file, and the model never knows it happened. There is no way for Claude to skip it, defer it, or forget about it. The determinism is total, and the context cost is zero because the hook runs outside the model entirely.
Why not a skill? You could write a skill that says “always run Prettier after editing files.” But skills are advisory. Claude might skip Prettier when it judges the edit too small to warrant formatting, or when it gets distracted by a more urgent subtask. That judgment is appropriate for procedural decisions but unacceptable for formatting enforcement. The moment you need the word “always” to mean literally always, you need a hook, not a skill. This is one of the clearest extensibility decisions you will encounter.
Decision Two: Encode a Team Deployment Checklist
Your team has a deployment runbook: run tests, verify staging, confirm migrations are reversible, tag the release, and post the changelog. You want Claude to follow this checklist when deploying. Walking through the axes, axis one asks about determinism. The answer here is no, because deployment involves judgment at each step. Maybe a test failure is a known flaky test that is safe to ignore. Maybe a migration requires manual review before proceeding.
Axis two asks about context isolation. The answer is no, because deployment steps need to play out in the main thread where you can see them, approve them, and intervene. Axis three asks whether this is a reusable procedure that activates when relevant. The answer is yes. This is a textbook skill.
Why not a hook? Hooks fire on tool events, not on conceptual workflows. There is no PreDeploy lifecycle event. You could theoretically chain hooks together, but the result would be brittle and impossible to steer interactively. A skill lets Claude walk through each step, pause for your confirmation, adapt when something unexpected happens, and ultimately hand you a deployment that you trust because you were in the loop the whole time. The skill is the right extensibility mechanism for any multi-step procedure that needs human judgment.
Decision Three: Audit Dependencies Without Cluttering Context
You want to check every dependency in a large monorepo for known vulnerabilities. The task involves reading dozens of manifest files, cross-referencing versions against advisory databases, and producing a prioritized report. Walking through the axes, axis two is the deciding factor. This task would flood your main context with hundreds of file reads and version strings.
A subagent solves this perfectly. You define a dependency-auditor agent that reads all the manifest files, does the cross-referencing in its own isolated context, and returns a clean summary listing vulnerable packages with severity levels and recommended actions. Your main session receives maybe two hundred tokens of summary instead of twenty thousand tokens of raw file data.
Why not a skill? A skill would run inline, meaning every file read and every version check would land in your main context. By the time the audit finished, you would have burned most of your context window on data you do not need to keep. Why not a hook? Hooks cannot do multi-step analysis; they fire once on an event and return. The subagent is the only extensibility mechanism designed for exactly this pattern: heavy lifting in isolation, clean summary on return. You can also route it to Haiku for cost savings, since vulnerability matching does not need frontier reasoning.
When Extensibility Tools Combine
The four mechanisms are not mutually exclusive. In fact, the most powerful extensibility setups combine them in deliberate ways. Three composition patterns are particularly valuable, and understanding them unlocks a higher level of workflow design that goes beyond picking one tool at a time.
The first pattern is a skill with scoped hooks. Skills can declare hooks in their frontmatter using a hooks: field. Those hooks activate only while the skill is running and deactivate when the skill session ends. This is ideal for opinionated hooks you do not want always-on. For example, a deployment skill might include a PreToolUse hook that blocks commits to the main branch during the deploy window. You want that enforcement only during deploys, not during normal development. Scoped hooks give you that precision without polluting your global configuration.
The second pattern is a subagent that preloads skills. The skills: frontmatter in an agent definition injects full skill content into the subagent’s context at startup. This means your dependency-auditor subagent can come pre-loaded with your team’s security review checklist, your vulnerability severity rubric, and your escalation procedure. The subagent starts its isolated work already knowing your standards, without you having to restate them each time. This composition is where extensibility starts to compound.
The third pattern is the plugin that bundles everything. Once you have a proven skill with scoped hooks, a subagent that preloads that skill, and an MCP server that provides vulnerability data, you have a coherent security workflow. Wrapping it all in a plugin lets your team install the entire setup with one command. The plugin manifest references each component, handles versioning, and ensures everyone runs the same configuration. This is the ultimate extensibility composition: primitives that work standalone, composed into a workflow, and distributed as a unit.
These composition patterns are why plugins exist. They are not a competing primitive. They are the mechanism for sharing compositions. You build the composition first, test each primitive in isolation, then package it. The plugin adds distribution, not capability. Understanding this distinction is the single most important conceptual leap in the Claude Code extensibility model.
A Worked Example: Choosing Extensibility for a Real Project
Imagine a mid-size engineering team setting up Claude Code for a monorepo with forty packages, three deployment targets, and a growing list of coding conventions. They want to get the most out of Claude Code’s extensibility surface without over-engineering their setup. Let us walk through their decisions step by step, the same way you would approach this for your own project.
The team starts with lint enforcement. Every file edit should trigger ESLint and Prettier, no exceptions. This is axis one, determinism, and the answer is absolute. They configure a PostToolUse hook in settings.json that runs the linter after every Edit and Write call. The hook runs outside the model, costs zero context tokens, and never misses. Within the first day, code style consistency across the monorepo improves dramatically, and review comments about formatting disappear entirely.
Next, the team tackles their deployment runbook. They have a twelve-step procedure that involves running tests, verifying staging builds, confirming migration reversibility, getting approval from the on-call engineer, and tagging the release. This procedure needs judgment at each step, and the team wants to stay in the loop during deploys. They write a skill called deploy-checklist that encodes the full procedure with conditional branches for each deployment target. When someone asks Claude to deploy, the skill auto-activates and walks through each step interactively.
The team then realizes their dependency surface is growing. Forty packages means forty package.json files and a sprawling lockfile. Auditing these for vulnerabilities inline would destroy their context. They create a subagent called dependency-auditor that reads all manifests, cross-references versions against advisory databases, and returns a prioritized report. They route it to Haiku to keep costs low, since vulnerability matching does not need frontier reasoning. The subagent preloads their security review skill so it knows the team’s severity rubric from the start.
Security review becomes the next extensibility target. The team wants Claude to check for common vulnerability patterns in new code. They write a skill that covers OWASP top ten checks for their stack. This skill includes scoped hooks that activate only during security reviews, blocking commits that introduce known-dangerous patterns like unparameterized SQL queries. The scoped hook approach means the enforcement is active only when relevant, not during routine feature development.
At this point, the team has a proven set of primitives: one hook for linting, two skills for deployment and security review, one subagent for dependency audits, and scoped hooks within the security skill. Each one works standalone and has been tested in production sessions. The team decides to package everything as a plugin called team-standards so that new engineers can install the entire setup with one command and everyone stays in sync as conventions evolve.
The plugin manifest references each component. It declares the lint hook, the deploy and security skills, the dependency auditor subagent, and the MCP server that provides advisory data. Versioning is handled through the plugin’s version field, and updates propagate when team members run /plugin update. The team also publishes the plugin to their internal marketplace so contractors and new hires get the same guardrails from day one.
This story illustrates the full extensibility lifecycle. The team did not start with a plugin. They started with individual primitives, each chosen through the decision axes. They tested each one in isolation. They discovered composition patterns that added value. Only then did they package everything as a plugin for distribution. This is the correct order of operations, and following it ensures that your extensibility architecture is built on proven, tested primitives rather than premature abstraction.
Notice also what the team did not do. They did not build a plugin before testing the primitives inside it. They did not create a subagent for a task that only took a few seconds inline. They did not encode a simple preference as a skill when a one-line CLAUDE.md note would suffice. The discipline of reaching for the simplest mechanism that solves the problem is what separates a well-designed extensibility architecture from a bloated one. Every primitive you create has a maintenance cost, a context cost, and a learning curve for new team members. Adding a primitive should be a deliberate choice, not a reflex.
Extensibility Adoption Stages
Teams do not adopt all four extensibility mechanisms at once. There is a natural progression that most teams follow, and understanding it helps you avoid over-investing in one mechanism before you have exhausted simpler options. The stages below describe a typical adoption curve.
Stage one is CLAUDE.md. Every team starts here. You write conventions, coding standards, and project context into CLAUDE.md. This is the simplest extensibility mechanism and requires zero configuration. But as the file grows past a few hundred lines, it starts consuming context tokens that would be better spent on reasoning. This is the signal to graduate to the next stage.
Stage two is hooks for enforcement. The team identifies tasks that must happen every time, like linting and formatting, and moves them from advisory CLAUDE.md instructions into deterministic hooks. This immediately pays dividends in consistency and frees context tokens. Most teams reach this stage within their first week of serious Claude Code usage.
Stage three is skills for procedures. Conventions that have grown into multi-step procedures get extracted from CLAUDE.md into dedicated skill files. This is where progressive disclosure starts paying off, because skills load only when relevant rather than consuming context permanently. Teams typically reach this stage after a month of daily use.
Stage four is subagents for heavy lifting. The team identifies tasks that flood context with intermediate results and moves them to subagents. This is often triggered by a specific pain point, like a dependency audit or a large codebase search that ate an entire context window. Stage five is plugins for distribution, where proven primitives get packaged for team-wide sharing. Not every team reaches stage five, and that is fine. Plugins add value only when distribution is a real need.
Testing and Iterating on Extensibility
Building extensibility primitives is an iterative process. Your first skill will not be perfect. Your first hook will have edge cases you did not anticipate. The key is to test each primitive in isolation before composing it with others, and to iterate based on real session feedback rather than theoretical completeness.
For skills, the testing loop is simple. Run a session where you would expect the skill to activate. Check whether it auto-matched correctly. Read the skill body afterward and ask whether Claude followed it, drifted from it, or ignored it entirely. If the skill drifted, tighten the instructions or add conditional logic. If it never triggered, rewrite the description to be more specific about what problem it solves. Iterate until the skill reliably activates and guides behavior in the way you intend.
For hooks, testing is more deterministic but still necessary. Trigger the lifecycle event manually and verify the hook fires. Check the exit code and output format. A PostToolUse hook that returns a non-zero exit code can block the tool call, which is powerful but also dangerous if the hook has a bug. Test your hooks against edge cases like empty files, binary files, and files with unusual encodings. A hook that crashes on an edge case can silently break your entire editing workflow.
For subagents, test the quality of the returned summary. The subagent might do excellent work internally but return a summary that is too vague, too verbose, or missing critical findings. Iterate on the subagent’s system prompt until the summary consistently contains the information you need. Also monitor the subagent’s token usage to ensure it is not burning more context than the task warrants. If a subagent consistently uses more tokens than doing the task inline would have cost, the subagent is not providing extensibility value.
The golden rule of extensibility iteration is to change one thing at a time. If you add a new skill, a new hook, and a new subagent in the same session, and something goes wrong, you cannot isolate the cause. Add primitives one at a time, verify each one in a real session, and only then compose them. This discipline feels slow but saves hours of debugging confused interactions between primitives that were never tested individually.
Extensibility: Common Mistakes to Avoid
The extensibility mechanisms are powerful, but they are also easy to misuse. The four mistakes below are the ones we see most often, and each one carries a real cost in wasted tokens, broken workflows, or confused architectures. Avoiding them from the start saves significant frustration.
- Putting “always run prettier” in CLAUDE.md instead of a PostToolUse hook. The model treats this as advisory and will skip formatting when distracted. Use a hook for guaranteed enforcement every single time.
- Writing a skill that restates what Claude would do anyway. A skill must add value beyond the model’s default behavior. If the instructions merely describe what Claude already does, the skill wastes five hundred tokens of context for no benefit.
- Using a subagent for iterative conversation. Subagents are one-shot workers. They cannot ask follow-up questions or refine their output through dialogue. For interactive tasks, keep the work in the main thread.
- Treating plugins as a fourth peer primitive. Plugins are a packaging layer, not a capability. Choosing “plugin” as an answer to “how do I solve this problem” is a category error. Pick a primitive first, then decide on packaging.

Extensibility: Best Practices
- Prefer the shortest-lived context. Hooks cost zero context, skills cost five hundred tokens when loaded, and CLAUDE.md costs forever. Always choose the mechanism with the smallest permanent footprint for your need.
- Scope skills with paths and when-to-use fields. A skill that loads on every session wastes tokens. Use path scoping and description matching so skills activate only when the current task genuinely needs them.
- Route subagents to cheaper models. Haiku handles dependency audits, log analysis, and file searches at a fraction of Sonnet’s cost. Reserve frontier models for tasks that need deep reasoning in the main thread.
- Reference the official Claude Code documentation as your source of truth. The extensibility surface evolves quickly, and the official docs always reflect the latest configuration syntax and lifecycle event names.
- Package as a plugin only once primitives are proven. Premature packaging locks you into an abstraction before you know the right shape. Test each skill, hook, and subagent in real sessions before bundling them.
Extensibility: Frequently Asked Questions
Should I use a skill or a hook for enforcing code style?
Use a hook. Code style enforcement requires absolute determinism, meaning the formatter must run after every edit without exception. Skills are advisory and the model can skip them. A PostToolUse hook fires every time, costs zero context tokens, and the model cannot opt out. For any extensibility requirement where the word “always” is non-negotiable, hooks are the answer.
When is a subagent better than a skill for extensibility?
A subagent is better when the task would flood your main context with noisy intermediate results. Deep searches, dependency audits, and log analysis all involve reading hundreds of files whose contents you do not need to keep. A subagent does that work in its own context and returns only a summary. Skills run inline, so they are wrong for context-heavy extensibility tasks.
Do I need a plugin to use skills and hooks together?
No. Plugins are a distribution layer, not a dependency. Skills and hooks work together without any plugin. You can declare scoped hooks in a skill’s frontmatter directly. You only need a plugin when you want to share a coherent set of extensibility primitives with a team or community through one-command install and versioning.
Can a skill include its own hooks for scoped enforcement?
Yes. Skills support a hooks: field in their frontmatter that activates hooks only while the skill is running. This is ideal for opinionated enforcement you do not want always-on. For example, a deploy skill can block main-branch commits during deploys without affecting normal development sessions. This composition pattern is one of the most powerful extensibility features available.
What is the cheapest extensibility mechanism in terms of context cost?
Hooks are the cheapest extensibility mechanism, with zero context cost. They run entirely outside the model, so no tokens are spent on their execution or output. Skills cost about five hundred tokens when loaded, and subagents cost roughly two hundred tokens for their returned summary. For any task expressible as a shell command, hooks are the clear winner on cost alone.
Extensibility in Claude Code comes down to four mechanisms and four decision axes. Ask whether your task needs determinism, context isolation, a reusable trigger, or distribution, and the answer emerges every time. Skills teach, Subagents isolate, Hooks enforce, Plugins distribute. Master this framework and you will never waste context on the wrong tool again.