Research Study · March 2026

Claude Code
Skills System

A comprehensive study of how Claude Code discovers, loads, injects, and manages skills at runtime — from SKILL.md frontmatter to context window budget enforcement.

60+ Skills Installed
3 Loading Stages
2 Injection Paths
18KB Max Injection Budget

What Are Skills?

Skills are reusable prompt templates that extend Claude's capabilities by injecting domain-specific instructions into conversations on-demand. Unlike CLAUDE.md (always loaded), skills use progressive disclosure.

Skills

  • Prompt-based instruction templates
  • User or Claude invoked
  • Lazy-loaded (on-demand)
  • Supports frontmatter controls
  • Can have supporting files
Recommended

Hooks

  • Event handlers for system events
  • Automatic (event-driven)
  • Run on matching events
  • Can inject additionalContext
  • PreToolUse / PostToolUse / etc.
Automation

Commands

  • Legacy prompt templates
  • User-only (/name)
  • Now merged with skills
  • Simpler frontmatter
  • No auto-invocation
Legacy

Agents

  • Specialized autonomous workers
  • Claude or user invoked
  • Isolated context
  • Custom system prompts
  • Full preload at startup
Isolated

Anatomy of a SKILL.md

skills/my-skill/SKILL.md
---
name: my-skill
description: "When to use this skill (max 250 chars)"
disable-model-invocation: false
user-invocable: true
allowed-tools: Read, Grep, Glob
model: claude-opus-4-6
effort: high
context: fork
metadata:
  priority: 8
  pathPatterns: ["app/api/chat/**"]
  bashPatterns: ["\\bnpm\\s+install"]
  promptSignals:
    phrases: ["ai sdk"]
    minScore: 6
---

# Markdown instructions here...
Full skill content loaded only on invoke.
Identity Name + description (always in context)
Invocation Control Who can trigger this skill
Execution Config Model, tools, effort, context
Plugin Triggers File/bash/prompt patterns for auto-injection
Skill Body Full instructions (lazy-loaded, 500-5K tokens)

Progressive Disclosure

Skills use a three-stage loading model to minimize context consumption. Only what's needed is loaded when it's needed.

1

Session Start

Names + descriptions of all enabled skills

~100 tokens/skill
SLASH_COMMAND_TOOL_CHAR_BUDGET Controls total budget (default: 1% of context, min 8K chars)
Always
On invoke
2

On Invocation

Full SKILL.md body loaded into conversation

~500-5,000 tokens/skill
PreToolUse: 18KB / 3-5 skills UserPromptSubmit: 8KB / 2 skills
User /name or Claude auto-detects
On access
3

On-Demand Files

Supporting files: reference.md, examples.md, scripts/

Variable (per file read)
Only loaded when Claude reads them via filesystem
Claude reads supporting files

Context Savings vs. CLAUDE.md

CLAUDE.md (50 skills)
~50K tokens (always)
Skills (50 loaded)
~5K tokens (startup)
Skills (3 invoked)
~11K tokens (active)

Injection Pipeline

Two independent paths inject skills at runtime. Each has its own budget, matching logic, and caps.

Path 1: PreToolUse

Trigger: Read / Edit / Write / Bash Budget: 18 KB Max: 3-5 skills
1
Parse Input Extract file path or bash command
2
Load Manifest Read compiled skill-manifest.json
3
Pattern Match Path globs, bash regex, import patterns
4
Rank + Boost Priority + profiler/TSX/dev-server boosts
5
Dedup Check Skip already-injected skills
6
Budget Enforce Inject top matches within 18KB cap

Path 2: UserPromptSubmit

Trigger: User types a message Budget: 8 KB Max: 2 skills
1
Score Prompt Match against promptSignals config
2
Phrase Match +6 per phrase, +4 allOf, +1 anyOf
3
Lexical Fallback Stemmer-based token matching
4
Rank Results Sort by relevance score
5
Dedup Check Skip already-injected skills
6
Budget Enforce Inject top 2 within 8KB cap

Priority Boost System

Boost Amount Condition
Base priority 1-9 From SKILL.md frontmatter metadata.priority
Profiler +5 Skills predicted at session start via project scanning
vercel.json routing ±10 Key-specific routing when editing vercel.json
TSX review +40 After 3+ .tsx file edits
Dev server +45 When dev server detected running

Prompt Signal Scoring

phrases
+6
+6
+6
Per exact phrase match (case-insensitive)
allOf
+4
+4
Per group where ALL terms present
anyOf
+1
+1
cap +2
Per optional term, capped at +2 total
noneOf
×
Hard suppress — skill excluded entirely
minScore threshold
6
Default: 6 points required to inject

Session Lifecycle

Skills are tied to the session lifecycle. Once loaded, they persist until the session ends or conversation is compacted.

Session Start
Read settings.json → enabledPlugins
Load all skill names + descriptions
Profile project → set LIKELY_SKILLS
Initialize dedup tracking
Inject base context (vercel.md, etc.)
Session Active
User Prompt UserPromptSubmit hook fires Max 2 skills, 8KB
Tool Use PreToolUse hook fires Max 3-5 skills, 18KB
File Write PostToolUse validates Regex checks on output
No mid-session unloading. Injected skills persist in context. Settings changes take no effect until restart.
Mid-Session Events
/compact Summarizes conversation. Dedup resets. Skills can re-inject.
/clear Clears history. Dedup resets. Descriptions remain loaded.
resume Full reload same as fresh session. History restored.
Session End
Cleanup temp dedup files
Next session reads fresh settings.json

Context Budget System

Multiple budget mechanisms work together to prevent skills from overwhelming the context window.

Layer 1: Description Budget

SLASH_COMMAND_TOOL_CHAR_BUDGET
~42 skills
8,000 chars
Default 1% of context window (min 8,000 chars)
Per skill 250 chars max per description (hard cap)
Override export SLASH_COMMAND_TOOL_CHAR_BUDGET=20000

Layer 2: PreToolUse Injection

VERCEL_PLUGIN_INJECTION_BUDGET
3-5 skills/invocation
18,000 bytes
Trigger Read / Edit / Write / Bash tool use
Selection Highest priority first until budget exhausted

Layer 3: Prompt Injection

VERCEL_PLUGIN_PROMPT_INJECTION_BUDGET
2 skills/prompt
8,000 bytes
Trigger Every user message submission
Selection Prompt signal scoring + lexical fallback

Deduplication

Skill matched
Check seen? VERCEL_PLUGIN_SEEN_SKILLS
Skip Already injected
Inject Add to seen list
Reset triggers: /clear /compact session end

Local Installation Audit

Inventory of all skill-bearing plugins installed on this machine.

V

Vercel Plugin

claude-plugins-official · v0.22.1
47 skills
Core
vercel-deploy vercel-cli vercel-api vercel-agent deployments-cicd vercel-flags
Next.js
nextjs next-upgrade next-cache-components routing-middleware
AI
ai-sdk ai-gateway chat-sdk ai-elements v0-dev
Infra
vercel-functions vercel-storage vercel-queues workflow turborepo turbopack
DX
bootstrap marketplace env-vars observability shadcn verification agent-browser
P

Plugin-Dev

claude-plugins-official
7 skills
skill-development plugin-structure command-development hook-development agent-development mcp-integration plugin-settings
F

Frontend Design

claude-code-plugins
1 skill
frontend-design
H

Hookify

claude-code-plugins (marketplace)
1 skill
writing-rules
D

Feature-Dev

claude-plugins-official
Multiple
code-explorer code-architect code-reviewer
R

Code-Review

claude-plugins-official
Multiple
code-review

Key Findings

Lazy Loading Works

Only ~100 tokens/skill at startup. Full content on-demand saves massive context vs. CLAUDE.md approach.

No Mid-Session Unloading

Once injected, skills persist. /compact is the closest workaround (resets dedup, compresses context).

No Hot-Reload

Plugin enable/disable requires session restart. settings.json is read once at startup.

!

Cloud Skill Injection

69 unwanted skills injected from claude.ai with no opt-out mechanism (GitHub #39686).

Smart Dedup

Per-session tracking prevents skill spam. Resets on /clear and /compact.

Configurable Budgets

Three env vars control description budget, PreToolUse injection, and prompt injection independently.