How to Use Plugins in Claude Code: From Basics to Building Your Own
Learn how to install, use, and create Claude Code plugins. A practical tutorial with real examples — from user to plugin creator.
How to Use Plugins in Claude Code
Out of the box, Claude Code is already impressive. It reads your code, edits files, runs commands, and answers questions about your project. But at some point, you'll want it to do things your way.
Maybe you want a /commit command that follows your team's conventions. Or a hook that blocks commits without tests. Or a specialized agent that runs code reviews with your company's criteria.
That's where plugins come in.
In this article, you'll learn what plugins are, how to install and use existing ones, and how to build your own from scratch. No unnecessary theory — just real examples.
What are plugins
A Claude Code plugin is a folder with a configuration file and a set of components that extend what Claude can do.
Think of it this way: Claude Code is like a new smartphone. It works great out of the box. But when you install apps — a better camera, a photo editor, a task manager — it adapts to your lifestyle. Plugins are Claude Code's apps.
In practice, a plugin is a folder with this minimal structure:
my-plugin/
├── .claude-plugin/
│ └── plugin.json ← plugin identity
├── skills/ ← behaviors Claude learns
├── commands/ ← slash commands (/my-command)
├── hooks/ ← automatic scripts (before/after actions)
└── agents/ ← specialized sub-agents
The plugin.json is the ID card. It tells Claude Code the plugin's name, what it does, and who made it:
{
"name": "my-plugin",
"description": "Automations for my development workflow",
"author": {
"name": "Your Name"
}
}
The rest are optional components. A plugin can have just one command. Or just hooks. Or a combination of everything. You build what you need.
Plugin components
Each component type solves a different problem. Here's what each one does:
Skills — teaching new behaviors
A skill is a Markdown file that teaches Claude how to perform a specific task. When invoked, the skill's content is loaded into the conversation context — as if you had pasted detailed instructions.
Example: a code review skill that defines specific criteria, checklists, and output format. When invoked, Claude knows exactly how to review code the way you want.
Skills are .md files with YAML frontmatter:
---
name: my-skill
description: Use when the user asks to do X
---
# Skill Instructions
Here go the detailed instructions that Claude
will follow when this skill is invoked.
The description field is critical — it's what lets Claude decide when to use the skill automatically.
Commands — slash shortcuts
Commands are custom slash commands. You type /my-command and Claude executes a predefined workflow.
The difference between a command and a skill: commands are explicitly invoked by the user (via /), while skills can be triggered automatically when Claude identifies they're relevant.
Real command examples:
| Command | What it does |
|---|---|
/commit |
Commit following Conventional Commits |
/code-review |
Code review a pull request |
/create-pr |
Create a PR linked to an issue |
Commands are also Markdown files with frontmatter:
---
description: Run a code review on a pull request
allowed-tools: Bash(gh *), Read, Grep, Glob
---
# Code Review
Instructions for Claude to execute the review...
The allowed-tools field defines which tools the command can use — an important security control.
Hooks — invisible automation
Hooks are scripts that run automatically in response to Claude Code events. They're invisible to the user — working behind the scenes.
The main events:
| Event | When it fires |
|---|---|
PreToolUse |
Before any tool executes |
PostToolUse |
After a tool finishes |
UserPromptSubmit |
When the user sends a message |
Stop |
When Claude finishes a response |
Practical example: a PreToolUse hook that checks if a Bash command is destructive (rm -rf, git push --force) and blocks execution with a warning.
Hooks are registered in hooks/hooks.json and executed by scripts (Python, bash, Node.js):
{
"hooks": {
"PreToolUse": [
{
"hooks": [
{
"type": "command",
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/pretooluse.py",
"timeout": 10
}
]
}
]
}
}
The ${CLAUDE_PLUGIN_ROOT} variable points to the plugin's root — always use it for relative paths.
Agents — specialized sub-agents
Agents are autonomous sub-processes that Claude can spawn for complex tasks. Think of them as the assistant's assistants.
Example: a code review agent that uses the Haiku model (faster and cheaper) for a first pass, and only escalates to the main model when it finds serious issues.
MCP Servers — connecting to the world
Plugins can include MCP (Model Context Protocol) server configurations, which connect Claude to external tools — databases, APIs, browsers, search services.
Quick comparison
| Component | Activation | Format | Typical use |
|---|---|---|---|
| Skill | Automatic or manual | Markdown | Teaching behaviors |
| Command | Manual (/command) |
Markdown | Repeatable workflows |
| Hook | Automatic (event) | Script + JSON | Validation, security |
| Agent | Via Claude | Markdown | Complex tasks |
| MCP | Always active | JSON config | External tools |
Installing and using plugins
There are two paths to get plugins in Claude Code: install from a marketplace or add them manually.
Marketplaces
Marketplaces are GitHub repositories that contain plugin collections. The main one is Anthropic's official marketplace (anthropics/claude-plugins-official), but anyone can create their own.
To add a marketplace:
/plugin marketplace add user/repository
To install a plugin from a marketplace:
/plugin install plugin-name
Claude Code downloads the plugin, places it in ~/.claude/plugins/cache/, and registers the installation.
Scope: user vs project
When installing, you choose the scope:
- User (global): The plugin works across all projects. Ideal for generic tools like code review, git workflows, frontend design.
- Project: The plugin works only in that project. Ideal for team-specific or stack-specific plugins.
Popular plugins from the official marketplace
These are real plugins from the anthropics/claude-plugins-official marketplace:
| Plugin | What it does | Recommended scope |
|---|---|---|
| code-review | Automated PR review with scoring | User |
| hookify | Create validation rules without code | User |
| frontend-design | High-quality design interfaces | User |
| plugin-dev | Tools for creating plugins | User |
| claude-md-management | Keep CLAUDE.md organized | User |
| context7 | Fetch up-to-date docs for any library | User |
| playwright | Browser automation for testing | User |
| firecrawl | Web scraping and search | Project |
| stripe | Stripe integration | Project |
Using plugins day to day
Once installed, plugins integrate naturally into Claude Code:
Commands appear as slash commands. Type / and you'll see available commands. Example:
> /code-review 42
This invokes the code-review plugin to review PR #42.
Skills are activated automatically when Claude identifies they're relevant. If you have the frontend-design skill installed and ask "create a login component," Claude will use the skill automatically.
Hooks run in the background. You don't need to do anything — they monitor events and act when needed.
Creating your first plugin
Let's build a real plugin: a /status command that shows a project state summary (git, tests, lint).
Step 1: Create the structure
In your project root (or in ~/.claude/plugins/ for global scope):
mkdir -p my-status-plugin/.claude-plugin
mkdir -p my-status-plugin/commands
Step 2: Create plugin.json
{
"name": "project-status",
"description": "Shows a quick summary of the project state",
"version": "1.0.0",
"author": {
"name": "Your Name"
}
}
Save it to my-status-plugin/.claude-plugin/plugin.json.
Step 3: Create the command
The command is a Markdown file in commands/:
---
description: Show project state summary (git, lint, tests)
allowed-tools: Bash(git *), Bash(pnpm *), Bash(npm *)
---
# Project Status
Generate a concise summary of the current project state:
1. **Git:** current branch, pending commits, modified files
2. **Lint:** run the linter and report errors (if configured)
3. **Tests:** run tests and report results (if configured)
Output format:
## Project Status
- **Branch:** main (2 commits ahead of origin)
- **Modified:** 3 files
- **Lint:** 0 errors, 2 warnings
- **Tests:** 14/14 passing
If a tool isn't configured, mention that instead
of failing silently.
Save as my-status-plugin/commands/status.md.
Step 4: Test it
For local (project) plugins, just place the folder in your project directory. Claude Code automatically detects the .claude-plugin/plugin.json folder.
Open Claude Code in the project and type:
> /status
Claude will read the command, execute the described steps, and present the summary.
Final structure
my-status-plugin/
├── .claude-plugin/
│ └── plugin.json
└── commands/
└── status.md
Three files. A working plugin.
Hooks: automating behaviors
Hooks are where plugins get really powerful. While commands and skills wait for your action, hooks act on their own.
Anatomy of a hook
A hook needs two things:
- Registration in
hooks/hooks.json— tells Claude Code when to run it - Script that executes the logic — receives JSON via stdin, returns JSON via stdout
Example: blocking dangerous commands
Let's create a hook that prevents destructive commands like rm -rf / or git push --force to main.
hooks/hooks.json:
{
"hooks": {
"PreToolUse": [
{
"hooks": [
{
"type": "command",
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/guard.py",
"timeout": 5
}
]
}
]
}
}
hooks/guard.py:
#!/usr/bin/env python3
"""Block destructive commands before execution."""
import json
import sys
import re
DANGEROUS_PATTERNS = [
r'rm\s+-rf\s+/',
r'git\s+push\s+.*--force.*\s+main',
r'git\s+reset\s+--hard',
r'drop\s+database',
]
def main():
input_data = json.load(sys.stdin)
tool_name = input_data.get('tool_name', '')
if tool_name != 'Bash':
print(json.dumps({}))
sys.exit(0)
command = input_data.get('tool_input', {}).get('command', '')
for pattern in DANGEROUS_PATTERNS:
if re.search(pattern, command, re.IGNORECASE):
result = {
"decision": "block",
"reason": f"Command blocked for safety: {command}"
}
print(json.dumps(result))
sys.exit(0)
print(json.dumps({}))
sys.exit(0)
if __name__ == '__main__':
main()
How it works
- The user (or Claude) tries to execute a Bash command
- Before execution, Claude Code calls
guard.py - The script receives command details via stdin (JSON)
- If the command matches a dangerous pattern, it returns
"decision": "block"— and the command doesn't execute - If the command is safe, it returns
{}— and execution proceeds normally
The hook always exits with sys.exit(0). If the hook crashes, Claude Code moves on — it never freezes because of a broken hook.
No code needed: hookify
If you don't want to write Python, the hookify plugin lets you create hook rules using just Markdown. You describe the rule in natural language and hookify handles the execution.
Next steps
Plugins transform Claude Code from a generic tool into your tool. Start simple:
- Install 2-3 plugins from the official marketplace and use them for a week
- Create a command for a workflow you repeat every day
- Add a hook for something that bugs you (e.g., commits without descriptive messages)
The official plugin documentation is constantly evolving. The best examples are the official marketplace plugins — read their code.
And if you want to go further — creating full plugins with agents, MCP servers, and advanced logic — the Curso Claude Code: Criador de Apps course covers this in depth, with real projects and step-by-step guidance.
References
- Discover and install prebuilt plugins through marketplaces — Official documentation on plugin installation and management
- Plugins reference — Complete technical reference for plugin architecture
- Create and distribute a plugin marketplace — How to create and distribute your own marketplace
- Hooks reference — Complete hooks reference: events, configuration, and input/output formats
- anthropics/claude-plugins-official — Anthropic's official marketplace on GitHub
- Plugins — Claude Code Docs — Guide to creating skills, agents, and hooks