Claude Code extension primitives
The terms blur together because they all "extend Claude Code" but they sit at different layers. The fastest way to keep them straight is to ask two questions about each one: when does it load, and who triggers it.
The mental model in one sentence: some files are always in front of Claude (CLAUDE.md), some are invoked on demand (Skills, Subagents, MCP), some fire automatically on events (Hooks), and some bundle everything together for sharing (Plugins).
The five layers
Each card below shows: the primitive, where it lives, and what it does in one line.
~/.claude/Project conventions, your role, tool preferences. Loaded every conversation.
Personal overrides that shouldn't be shared with the team.
Claude-written notes that persist across conversations. You don't edit these by hand.
Reusable workflows. Only the frontmatter description sits in context. Full body loads when Claude picks it.
Specialized workers with their own context window. Claude delegates via the Agent tool.
External tool providers. Show up as extra tools (e.g. an n8n MCP exposes workflow tools).
Shell commands triggered by events: PreToolUse, PostToolUse, UserPromptSubmit, Stop, SessionStart.
The harness config. Hooks, permissions, env vars, model selection, statusline, skillOverrides.
Type /name in chat to expand. Newer projects use user-invocable Skills instead -- same effect, more features.
A packaging format. Bundles skills, hooks, slash commands, subagents, and MCP servers into one shareable unit.
Quick reference
| Primitive | Location | Who triggers | When loaded |
|---|---|---|---|
| CLAUDE.md | project root | (automatic) | Every turn |
| Skills | .claude/skills/<name>/ | Claude (picks it) | On invocation |
| Subagents | .claude/agents/<name>.md | Claude (delegates) | On invocation, separate context |
| Hooks | settings.json | Harness (on event) | Deterministic, every matching event |
| Slash commands | .claude/commands/<name>.md | You type /name | When typed |
| MCP servers | .mcp.json | Configured, then Claude calls tools | Tools listed every turn, invoked on demand |
| settings.json | .claude/settings.json | Harness (reads at start) | Session start |
| Memory | ~/.claude/projects/.../memory/ | Claude (writes it) | Across conversations |
| Plugins | .claude-plugin/plugin.json | Installer | Bundles all of the above |
Each one in detail
CLAUDE.md and CLAUDE.local.md
Static text files. CLAUDE.md sits at the project root (or in subdirs for scoped instructions, or in ~/.claude/ for user-wide). It is loaded into context every conversation. Use it for project conventions, your role, tool preferences.
CLAUDE.local.md is the git-ignored variant for personal overrides.
Trade-off: always-on means it eats context. Keep it tight. Heavy reference material belongs in linked files or skills, not inline.
Skills
A skill is a folder: .claude/skills/<name>/SKILL.md, plus any helper scripts or references in the same folder.
The SKILL.md file has YAML frontmatter (at minimum name and description). Only the description is loaded into context up front. Claude reads descriptions of all available skills, then reads the full SKILL.md when it decides the skill is relevant.
Skills are auto-discovered from .claude/skills/ in your current directory, walking up to the repo root, plus ~/.claude/skills/ for user-wide skills.
Use when: you have a recurring workflow you want Claude to pick up on autonomously.
Subagents
A subagent is a markdown file at .claude/agents/<name>.md with YAML frontmatter (name, description, tools, optional model, permissionMode, etc.).
Each subagent runs with its own context window. Claude delegates work to them via the Agent tool. Useful for parallel work, scoped tool access, or protecting the main context from large search results.
Use when: you want isolated research or specialised work that shouldn't pollute the main conversation.
Hooks
Shell commands the harness runs automatically on events. Configured in settings.json:
PreToolUse/PostToolUse-- before or after a tool callUserPromptSubmit-- when you press enterStop-- when Claude finishes its turnSessionStart-- new session
Claude doesn't choose to fire hooks. The harness does. That's the key distinction from skills.
Use when: you want deterministic automation -- auto-format after edits, block dangerous commands, log activity, inject context.
Plugins
A packaging format. A plugin bundles skills, hooks, slash commands, subagents, and MCP servers into one installable unit, defined by a .claude-plugin/plugin.json manifest.
Installed from a marketplace or local path. Think of plugins as the "npm package" of Claude Code extensions.
Use when: you want to share a coherent set of extensions with others, or reuse them across machines.
Slash commands
Custom prompts in .claude/commands/<name>.md. Type /name in chat to expand. Different from skills because you trigger them explicitly.
Newer Claude Code projects merge slash commands into skills (a user-invocable skill produces /name as well, with extra features). Both .claude/commands/ and user-invocable skills work today; skills are the path forward.
MCP servers
External tool providers via the Model Context Protocol. Configured in .mcp.json or in settings.json. They expose extra tools to Claude (e.g. an n8n MCP exposes workflow management tools).
MCP is how you give Claude access to systems outside its built-in toolset.
settings.json
The harness config. Lives at .claude/settings.json (project) or ~/.claude/settings.json (user). Controls hooks, permissions, env vars, model selection, statusline, and skill overrides.
settings.local.json is the git-ignored variant for personal config.
Memory
Files Claude writes itself, persisted across conversations. Stored under ~/.claude/projects/<slug>/memory/, indexed by a MEMORY.md file.
Memory is for stable facts about you, your project, and your preferences. Not for in-progress task state.
Bundled skills (built-ins)
Claude Code ships with built-in skills you can call directly without writing your own: /loop, /run, /verify, /security-review, /review, /init, /claude-api, and more. They behave the same as project skills but live inside the binary.
Decision guide
| I want to... | Use |
|---|---|
| Tell Claude how this project works | CLAUDE.md |
| Add a personal override that isn't shared with the team | CLAUDE.local.md |
| Build a reusable workflow Claude picks up on its own | Skill |
| Delegate research without polluting context | Subagent |
| Run a script every time Claude edits a file | Hook (PostToolUse) |
| Block dangerous commands before they run | Hook (PreToolUse) |
Type /foo to expand a prompt | Slash command (or user-invocable skill) |
| Give Claude access to an external system | MCP server |
| Share a set of extensions with others | Plugin |
| Have Claude remember something across sessions | Memory (Claude writes it itself) |
| Change permissions, model, or env | settings.json |
A few terms that confuse people
"agents.md" -- there is no single agents.md file in Claude Code. Each subagent gets its own file in .claude/agents/. The single-file AGENTS.md exists in Codex, not Claude Code -- a common source of confusion if you've worked with both.
"Skills vs slash commands" -- a user-invocable skill produces a slash command. The mechanisms overlap. Prefer skills going forward; they have more features and are where the platform is heading.
"Skills vs subagents" -- skills run in the main conversation context. Subagents run in their own context window. Use a subagent when you want isolation (parallel work, large search results, scoped tools).
Related
- Cheatsheet -- the slash commands and file references I actually use
- Embed Codex in workspace -- running Claude Code alongside Codex
- Tool-agnostic setup -- one project, multiple coding agents