Claude Code Skills: Building Specialized AI Workflows

Listen to this article
Click ▶ to start
0%

A Skill in Claude Code is a specialized workflow that Claude can invoke automatically or you can trigger manually with a slash command. Unlike CLAUDE.md rules (which advise on every decision) or Hooks (which enforce deterministic actions), Skills are progressive disclosure — deep knowledge that loads only when relevant, keeping your base context lean while providing specialized expertise when needed.

This guide covers how Skills work, when to use them, and how to build real Skills that serve developers, testers, and DevOps engineers.


What Is a Skill?

A Skill is a .md file that teaches Claude how to do something specific — deeply. It lives in .claude/skills/ and contains:

  • A frontmatter header with metadata (name, description, allowed tools)
  • Detailed instructions for a workflow or task type
  • Examples and step-by-step guidance

Skills differ from other Claude Code tools:

ToolPurposeLoads when
CLAUDE.mdRules that apply to every decisionEvery session, always
SkillsDeep knowledge for specific workflowsYou invoke them, or automatically when relevant
HooksDeterministic automation (no exceptions)Specific lifecycle events (PreToolUse, PostToolUse, etc.)
SubagentsIsolated specialist assistantsYou delegate a task to them

Skills are the sweet spot: they contain knowledge that would bloat CLAUDE.md if always loaded, but are specialized enough that they shouldn’t be in the base system prompt.


Skill Structure

Create a skill in .claude/skills/my-skill-name/SKILL.md:

.claude/
└── skills/
    └── my-skill-name/
        └── SKILL.md

Inside SKILL.md, start with frontmatter:

---
name: my-skill-name
description: What this skill does in one sentence
user-invocable: true              # can you call /my-skill-name manually?
allowed-tools:                    # restrict what tools Claude can use
  - Read
  - Bash
  - Edit
disable-model-invocation: true    # optional: for workflows with side effects you want to trigger explicitly
---

# Skill: My Skill Name

[Your detailed instructions here]

Frontmatter Fields

FieldPurposeExample
nameSkill identifier (used in /skill-name command)run-tests
descriptionOne-sentence summary shown in helpRun tests and report coverage
user-invocableCan you manually invoke this with /skill-name?true or false
allowed-toolsRestrict which tools Claude can use[Bash, Read, Edit]
disable-model-invocationRequire explicit trigger (no auto-invocation)true for side-effect workflows

Invoking Skills

Manually — type the slash command:

/my-skill-name
/my-skill-name with arguments

Automatically — Claude recognizes when the skill is relevant and invokes it without you asking. To enable auto-invocation, include trigger patterns in your skill description:

---
name: run-tests
description: >
  Run the test suite and report coverage.
  Auto-invokes when the user asks to "run tests", "test this", or "check coverage".
user-invocable: true
---

When Claude sees a prompt like “run the test suite,” it recognizes the skill matches and invokes it.


Real Skill Examples for Each Audience

Skill 1: Test Runner (For Developers)

Developers need to run tests frequently but with nuance — sometimes you want a single test file, sometimes the full suite, sometimes only tests matching a pattern.

---
name: run-tests
description: >
  Run the test suite with filtering and coverage reporting.
  Auto-invokes when asked to "run tests", "test this", or "check coverage".
user-invocable: true
allowed-tools:
  - Bash
  - Read
---

# Test Runner Skill

## Workflow

1. Understand what the user wants to test (all tests, single file, pattern match)
2. Run the appropriate test command
3. Parse the output and report results
4. Show coverage if requested

## Commands

```bash
# Run all tests
npm test

# Run single file
npm test -- path/to/test.ts

# Run tests matching a pattern
npm test -- --testNamePattern "auth"

# Run with coverage
npm test -- --coverage

Steps

  1. Ask for clarification if needed: “Which tests? All, a specific file, or a pattern?”
  2. Run the command using the appropriate filter
  3. Interpret output:
    • Passing: list count and mark ✓
    • Failing: show assertion errors
    • Coverage: show percentage and uncovered lines
  4. Suggest next steps:
    • Tests pass: “All passing. Coverage 87%. Ready to commit.”
    • Tests fail: “3 failed. Here’s what broke. Fix before committing.”

### Skill 2: Cross-Browser Test Coordinator (For Testers)

Testers need to run tests across multiple browsers and capture screenshots for comparison.

```markdown
---
name: cross-browser-test
description: >
  Run tests across Chrome, Firefox, and Safari using Playwright.
  Auto-invokes when asked to "test across browsers" or "cross-browser test".
user-invocable: true
allowed-tools:
  - Bash
  - Read
  - Edit
---

# Cross-Browser Test Coordinator Skill

Test the same flows against:
- Chrome (desktop)
- Firefox (desktop)  
- Safari (desktop)
- Mobile Chrome (simulated iPhone)

## Workflow

1. Read the test file to understand test cases
2. Run across all browser configurations:
```bash
npx playwright test tests/e2e/checkout.spec.ts --project=chromium
npx playwright test tests/e2e/checkout.spec.ts --project=firefox
npx playwright test tests/e2e/checkout.spec.ts --project=webkit
npx playwright test tests/e2e/checkout.spec.ts --project="Mobile Chrome"
  1. Capture and compare screenshots

  2. For visual differences:

    • List which browsers show differences
    • Show screenshot diffs
    • Recommend: update baseline if intended, or investigate if unexpected
  3. Report structured results:

✓ Chrome — 3 passed
✓ Firefox — 3 passed
⚠ Safari — 2 passed, 1 visual diff
⚠ Mobile Chrome — 2 passed, 1 layout shift

Action items:
- Safari button styling: investigate CSS
- Mobile layout: review responsive breakpoints

### Skill 3: Infrastructure Audit (For DevOps)

DevOps engineers need to audit infrastructure for security, compliance, and drift.

```markdown
---
name: infra-audit
description: >
  Audit Terraform/Kubernetes for security issues, compliance violations, and drift.
  Auto-invokes when asked to "audit infrastructure" or "security check".
user-invocable: true
allowed-tools:
  - Bash
  - Read
  - WebFetch
---

# Infrastructure Audit Skill

## Audit checklist

### Security
- No hardcoded secrets (passwords, API keys, credentials)
- All network traffic encrypted in transit (TLS/HTTPS)
- IAM policies follow least-privilege (no `*` permissions)
- Database backups are encrypted and off-site
- VPC security groups restrict inbound to necessary ports only

### Compliance
- All resources tagged with owner, cost center, environment
- Logging enabled on all data stores (CloudTrail, VPC Flow Logs, RDS logs)
- Retention policies comply with regulatory requirements (GDPR, SOC2, etc.)
- Encryption keys managed (not inline, use AWS KMS or HashiCorp Vault)

### Operational
- No single point of failure (replicas/multi-AZ for critical services)
- Resource limits and requests configured (prevents node exhaustion)
- Monitoring/alerting configured for critical metrics
- Disaster recovery plan documented and tested

## Workflow

1. Gather infrastructure code:
```bash
find infra -name "*.tf"
find k8s -name "*.yaml"
  1. Scan Terraform for:

    • Hardcoded values
    • Missing tags
    • Overly broad IAM permissions
    • Encryption settings
  2. Scan Kubernetes for:

    • Resource requests/limits
    • Image registries (no public registries for private code)
    • Secrets handling
    • RBAC policies
  3. Check for drift:

terraform plan -out=plan.json
  1. Generate report:
## Infrastructure Audit Report — [DATE]

**Status**: [✓ Secure | ⚠ Warnings | ✗ Critical]

### Critical Issues
- Issue 1: [Impact] — Fix: [Action]

### Warnings
- Warning 1: [Impact] — Recommendation: [Action]

### Passing checks
- ✓ Secrets in AWS Secrets Manager
- ✓ Multi-AZ RDS
- ✓ Security groups restricted
- ✓ All resources tagged

### Action items
1. [Priority 1 fix]
2. [Priority 2 fix]

---

## When to Use Skills

**Use a Skill when:**
- The workflow is complex (more than 5 steps)
- You use it repeatedly across projects
- It requires deep knowledge that would bloat CLAUDE.md
- Different team members need different variants

**Don't use a Skill when:**
- It's a simple one-liner that CLAUDE.md can cover
- It's too specialized to one project
- It's a rule that must always apply (use CLAUDE.md instead)
- It's a deterministic action with zero exceptions (use Hooks)

---

## Skills vs Other Tools

| Tool | Best for | Invoked how | Token cost |
|------|----------|------------|-----------|
| **CLAUDE.md** | Conventions and rules | Always active | High (always loaded) |
| **Skills** | Complex multi-step workflows | Manual `/skill-name` or auto | Low (loads on demand) |
| **Hooks** | Deterministic enforcement | Specific events (no choice) | Medium (fires on events) |
| **Subagents** | Isolated specialists | Explicit delegation | Medium (separate context) |

**Decision tree:**
- "I want Claude to always follow this rule" → CLAUDE.md
- "I want this workflow automated but invoked on demand" → Skill
- "I want this to happen every time with no exceptions" → Hook
- "I want a specialist assistant with fresh context" → Subagent

---

## Tips for Effective Skills

**1. Be specific about what the skill does**

❌ Bad: "Development helper"
✓ Good: "Run unit tests, report failures, and suggest fixes"

**2. Use allowed-tools to restrict access**

```markdown
---
allowed-tools:
  - Read
  - Bash(npm test)
  - Bash(npm run build)
---

Claude can only run those specific commands.

3. Include examples in the skill

Show expected output format so Claude knows what you want to see.

4. Test the skill first

/skill-name test-arg

Verify it works as expected before relying on it.


Sharing Skills Across Projects

For skills you use everywhere:

mkdir -p ~/.claude/skills/my-skill-name
cp your-skill-content ~/.claude/skills/my-skill-name/SKILL.md

Global skills load in every project.


Common Mistakes

1. Skills too long (>500 lines)

Break into smaller skills. A 500-line skill means loading too much context.

2. Auto-invocation too broad

“Auto-invokes when user mentions testing” is too broad. Be specific: “when user asks to ‘run tests’ or ’test this’”.

3. No error handling

Include contingency steps:

  • “What if the test file doesn’t exist?”
  • “What if the deployment fails?”

4. Mixing concerns

One skill per responsibility. Don’t combine “test, build, lint, deploy” — make four separate skills.


Claude Code Skills bridge general guidance (CLAUDE.md) and deterministic automation (Hooks). Invest in well-written Skills and your daily workflows become significantly faster.

Abhay

Abhay Pratap Singh

DevOps Engineer passionate about automation, cloud infrastructure, and self-hosted tools. I write about Kubernetes, Terraform, DNS, and everything in between.