How to Use Skills with Claude Code: A Complete Practical Guide
Claude Code is Anthropic's AI-powered coding assistant that operates directly in your terminal, capable of reading, writing, and executing code across your entire project. One of its most powerful features is the ability to leverage 'skills' — specialized capabilities and workflows that extend what Claude Code can do beyond simple question-answering. These skills allow Claude Code to autonomously handle complex, multi-step engineering tasks like debugging pipelines, writing test suites, refactoring large codebases, and even managing version control operations.
Understanding how to effectively invoke and direct skills in Claude Code is the difference between using it as a glorified autocomplete tool and using it as a true autonomous engineering assistant. When you know how to frame requests, chain skills together, and configure Claude Code's environment, you unlock dramatically faster development cycles and higher-quality outputs.
In this guide, you will learn how to install and configure Claude Code, understand the categories of built-in skills it offers, craft precise prompts to invoke those skills, and build practical workflows for real development tasks like testing, refactoring, and documentation. By the end, you will have a repeatable system for integrating Claude Code's skill-based capabilities into your daily engineering work.
- Node.js 18+ installed on your machine
- An Anthropic API key (obtainable from console.anthropic.com)
- Basic familiarity with the terminal/command line
- A code project (any language) to practice with
- npm or a package manager installed
Install Claude Code and Authenticate Your API Key
Before you can use any skills, you need to install Claude Code globally via npm and connect it to your Anthropic account. Open your terminal and run the install command below. Once installed, you will authenticate by setting your API key as an environment variable. The best practice is to add this to your shell profile (e.g., ~/.bashrc, ~/.zshrc) so it persists across sessions. After setting the key, verify the installation by running `claude --version`. You should see a version number printed to the console, confirming a successful install. If you encounter a permission error during the npm install, prefix the command with `sudo` on macOS/Linux or run your terminal as Administrator on Windows. Claude Code connects to Anthropic's API on each invocation, so a stable internet connection is required during use.
# Install Claude Code globally
npm install -g @anthropic-ai/claude-code
# Set your API key (add this line to ~/.zshrc or ~/.bashrc for persistence)
export ANTHROPIC_API_KEY="sk-ant-your-key-here"
# Reload your shell config
source ~/.zshrc
# Verify installation
claude --version
Initialize Claude Code Inside Your Project Directory
Claude Code's skills become significantly more powerful when it has full context of your project. Navigate into your project's root directory and launch Claude Code interactively. When Claude Code starts, it automatically reads your directory structure, key configuration files (package.json, pyproject.toml, Makefile, etc.), and any CLAUDE.md file you have created. This context-loading phase is what enables skills like refactoring and testing to work accurately — Claude Code knows your file layout, dependencies, and coding conventions before you ask it to do anything. You will see an interactive REPL prompt appear in your terminal. Think of this as opening a conversation with an engineer who has just been onboarded to your codebase. Always start Claude Code from the root of the project you want it to work on, not from your home directory.
# Navigate to your project root
cd /path/to/your/project
# Launch Claude Code in interactive mode
claude
# You should see a prompt like:
# Claude Code v1.x.x
# Working directory: /path/to/your/project
# >
# Alternatively, run a one-off command without interactive mode
claude -p "Describe the structure of this project"
Understand the Core Skill Categories Available in Claude Code
Claude Code ships with several categories of built-in skills that you invoke through natural language prompts. Understanding these categories helps you craft better requests. The main skill categories are: (1) File Operations — reading, creating, editing, and deleting files across your project; (2) Code Execution — running scripts, tests, and build commands directly in your terminal environment; (3) Search and Analysis — searching codebases with grep-like precision, analyzing dependencies, and understanding code flow; (4) Git and Version Control — staging files, writing commit messages, creating branches, and reviewing diffs; (5) Debugging — identifying errors in stack traces, proposing and applying fixes; (6) Testing — generating unit and integration tests, running test suites, and interpreting results; (7) Documentation — writing inline comments, README files, and API documentation. Skills can be combined in a single prompt, allowing Claude Code to perform multi-step workflows autonomously without you needing to issue one command at a time.
# Example prompts that invoke different skill categories:
# File Operations skill
> Create a new file called utils/dateFormatter.js with a function that formats ISO dates
# Code Execution skill
> Run the test suite and show me which tests are failing
# Git skill
> Stage all changed files and write a conventional commit message describing the changes
# Debugging skill
> Here is my stack trace: [paste error]. Find the root cause and fix it.
# Documentation skill
> Add JSDoc comments to every exported function in src/api/userService.js
Create a CLAUDE.md File to Configure Skill Behavior
The CLAUDE.md file is a special configuration document you place in your project root that acts as persistent instructions for Claude Code. Think of it as an onboarding document for your AI assistant — you define coding standards, preferred patterns, commands to avoid, testing frameworks in use, and any project-specific context. Claude Code reads this file every time it starts in that directory, meaning the skills it applies will be shaped by your rules. For example, if you specify 'always write tests in Vitest, not Jest' in CLAUDE.md, the testing skill will respect that. You can also use CLAUDE.md to define custom workflows, specify which directories are off-limits, or describe the architecture of your system. This is one of the most impactful configurations you can make — a well-crafted CLAUDE.md dramatically improves the accuracy and relevance of every skill invocation.
# Create a CLAUDE.md file in your project root
touch CLAUDE.md
# Example CLAUDE.md content:
cat > CLAUDE.md << 'EOF'
# Project: My E-Commerce API
## Tech Stack
- Runtime: Node.js 20 with TypeScript
- Framework: Express.js
- Database: PostgreSQL via Prisma ORM
- Testing: Vitest (NOT Jest)
- Linting: ESLint with Airbnb config
## Coding Standards
- Always use async/await, never raw Promises
- All functions must have explicit TypeScript return types
- Error handling must use the AppError class in src/errors/AppError.ts
- Never commit secrets or hardcode API keys
## Key Commands
- Run tests: npm run test
- Build: npm run build
- Lint: npm run lint
## Off-Limits Directories
- Do not modify anything in /migrations directly
EOF
Use the File Editing Skill to Modify Code Safely
Claude Code's file editing skill is one of the most frequently used capabilities. When you ask Claude Code to edit a file, it uses a precise diff-based approach — it shows you exactly what will change before applying it, giving you the opportunity to approve or reject the modification. To invoke this skill effectively, be specific about the file path, the exact behavior you want changed, and any constraints. Claude Code will read the current file contents, reason about the necessary changes, display a diff, and then apply the edit after your confirmation. You can also use the `--dangerously-skip-permissions` flag in automated pipelines to skip confirmation prompts, but never do this on critical production files without a safety net like git. Always work in a git repository so you can revert changes if needed. The edit skill works best when your request targets a single, well-defined behavior change.
# Example: Asking Claude Code to edit a specific file
> Edit src/utils/validation.js to add input sanitization to the validateEmail function.
> It should strip whitespace and convert to lowercase before validating.
# Claude Code will show a diff like:
# --- src/utils/validation.js (before)
# +++ src/utils/validation.js (after)
# @@ -12,7 +12,9 @@
# function validateEmail(email) {
# - const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
# - return emailRegex.test(email);
# + const sanitized = email.trim().toLowerCase();
# + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
# + return emailRegex.test(sanitized);
# }
# Type 'yes' or press Enter to apply the change
# Type 'no' to reject it
Invoke the Testing Skill to Generate and Run Tests
The testing skill is one of the most valuable in Claude Code's arsenal. You can ask it to generate tests for existing code, run your test suite and interpret the results, or fix failing tests. When generating tests, provide Claude Code with the file you want tested and any specific edge cases you care about. Claude Code will read the source file, infer the function signatures and expected behaviors, write tests matching your framework (as defined in CLAUDE.md), and save them to an appropriate test file. It will then offer to run the tests immediately so you can see if they pass. When running existing tests, Claude Code not only executes the command but also reads the output, identifies root causes of failures, and can propose fixes — all in the same session. This makes the red-green-refactor cycle dramatically faster.
# Generate tests for a specific module
> Write unit tests for src/services/orderService.js.
> Cover the createOrder, cancelOrder, and getOrderById functions.
> Include edge cases for invalid inputs and database errors.
# Run the test suite and fix failures
> Run npm run test and fix any failing tests you find
# Example: Claude Code generates a test file
# src/services/__tests__/orderService.test.js
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { createOrder, cancelOrder, getOrderById } from '../orderService';
import { prisma } from '../../db/client';
vi.mock('../../db/client');
describe('orderService', () => {
beforeEach(() => {
vi.clearAllMocks();
});
describe('createOrder', () => {
it('should create an order with valid inputs', async () => {
const mockOrder = { id: '1', userId: 'user-1', total: 99.99 };
prisma.order.create.mockResolvedValue(mockOrder);
const result = await createOrder({ userId: 'user-1', total: 99.99 });
expect(result).toEqual(mockOrder);
});
it('should throw AppError when userId is missing', async () => {
await expect(createOrder({ total: 99.99 })).rejects.toThrow('userId is required');
});
});
});
Use the Git Skill to Manage Version Control Workflows
Claude Code has deep integration with git and can handle everything from staging files to writing descriptive commit messages to resolving merge conflicts. The git skill is particularly useful for writing high-quality conventional commit messages — instead of writing 'fixed stuff', Claude Code analyzes your staged diff and writes a detailed, properly formatted commit message. You can also ask it to create a new feature branch, squash commits before a PR, or review what has changed since your last commit. For teams following conventional commits or specific commit message standards, include those rules in your CLAUDE.md so the git skill applies them automatically. One powerful workflow is asking Claude Code to review your changes and suggest whether they should be split into multiple focused commits rather than one large commit — this improves your git history significantly.
# Ask Claude Code to handle a full git workflow
> Stage all modified files in src/, write a conventional commit message
> based on the changes, and commit them.
# Review changes and get a commit message
> Look at my unstaged changes and write a conventional commit message for them.
# Claude Code might produce:
# git add src/services/orderService.js src/utils/validation.js
# git commit -m "feat(orders): add input validation and sanitization to order creation
#
# - Add email sanitization (trim + lowercase) in validateEmail utility
# - Validate required fields in createOrder before database write
# - Throw typed AppError for missing userId and invalid amounts
#
# Closes #142"
# Create a new branch for a feature
> Create a new branch called feature/user-authentication and switch to it
# Resolve a merge conflict
> I have a merge conflict in src/config/database.js. Help me resolve it.
Chain Multiple Skills Together for Complex Workflows
The real power of Claude Code emerges when you chain multiple skills in a single, well-described prompt. Instead of issuing five separate commands, you describe the end goal and Claude Code orchestrates the skills needed to get there. For example, you might say: 'Refactor the authentication module to use JWT instead of sessions, update the relevant tests, and then run the test suite to confirm nothing is broken.' Claude Code will use the file editing skill, the testing skill, and the code execution skill in sequence, pausing to show you changes and ask for confirmation at key steps. When writing multi-skill prompts, structure them clearly — describe the main goal first, then list constraints. Avoid overloading a single prompt with too many unrelated goals, as this can cause Claude Code to lose focus. For very large tasks, break them into two or three connected prompts within the same session.
# Example: A multi-skill chained workflow prompt
> Do the following in order:
> 1. Read src/auth/sessionAuth.js and understand how it works
> 2. Create a new file src/auth/jwtAuth.js that implements the same interface using JWT
> 3. Update src/middleware/authenticate.js to use jwtAuth instead of sessionAuth
> 4. Update any existing tests in src/auth/__tests__/ to test JWT behavior
> 5. Run the test suite and fix any failures
> 6. Show me a summary of all files changed
# Another example: Bug investigation and fix workflow
> I'm seeing this error in production logs:
> "TypeError: Cannot read properties of undefined (reading 'userId')"
> at processWebhook (src/webhooks/stripeHandler.js:47)
>
> Find the root cause, fix it, add a test that would have caught this bug,
> and run the tests to confirm the fix works.
Use Headless Mode for Automation and CI/CD Pipelines
Claude Code can be run in headless (non-interactive) mode using the `-p` flag, which is essential for integrating its skills into automated pipelines, pre-commit hooks, or CI/CD workflows. In headless mode, you pass your prompt directly as a string argument and Claude Code executes the task and exits, printing output to stdout. This allows you to use Claude Code's skills programmatically — for example, automatically generating a PR description from a git diff, running a code review as part of a CI check, or auto-generating changelog entries. Be cautious with headless mode in CI environments: use scoped permissions, never include your API key directly in pipeline config files (use secrets managers), and always test headless commands locally before pushing. The `--output-format json` flag produces machine-readable output, which is useful when you need to parse Claude Code's responses in scripts.
# Run Claude Code in headless mode with -p flag
claude -p "Review the changes in the last git commit and list any potential bugs"
# Use in a shell script
#!/bin/bash
# auto-pr-description.sh
DIFF=$(git diff main...HEAD)
claude -p "Write a GitHub Pull Request description for this diff: $DIFF"
# CI/CD example: Add to .github/workflows/review.yml
# - name: AI Code Review
# run: |
# claude -p "Review the staged changes for security vulnerabilities
# and coding standard violations. Output issues as a bulleted list."
# env:
# ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
# Generate changelog entry
claude -p "Based on the git log since the last tag, write a CHANGELOG.md entry \
following Keep a Changelog format" >> CHANGELOG.md
# JSON output for scripting
claude --output-format json -p "List all TODO comments in the src/ directory"
Debug and Iterate on Skill Prompts for Better Results
Getting the best results from Claude Code's skills is an iterative process. If a skill invocation produces an incorrect or suboptimal result, the fastest path to improvement is to refine your prompt in the same session rather than starting over. Use follow-up messages like 'That's not quite right — the function should also handle null inputs' or 'Revert that last change and try a different approach'. Claude Code maintains conversation context within a session, so it remembers what it has already done. For debugging skill quality issues, try adding more constraints to your prompt, referencing specific line numbers or function names, and explicitly stating what you do NOT want. If you find yourself repeating the same prompt refinements across multiple sessions, add those constraints to your CLAUDE.md so they are automatically applied. Keep a personal notes file of high-quality prompts that worked well — these become reusable templates for your most common development workflows.
# Iterative prompt refinement example within a session:
# First attempt
> Add error handling to the fetchUserData function in src/api/users.js
# Claude Code adds generic try/catch, but you want something more specific:
> That's not what I need. Revert that change. Instead, wrap fetchUserData
> in a retry mechanism that retries up to 3 times on network errors (5xx status codes)
> but immediately throws on client errors (4xx). Use exponential backoff.
# If Claude Code misunderstands your architecture:
> The AppError class I mentioned is at src/errors/AppError.ts —
> look at that file first, then apply the error handling using that class.
# Asking for a self-review before finalizing
> Before saving that change, review it yourself for:
> 1. TypeScript type correctness
> 2. Proper use of our AppError class
> 3. Any edge cases you may have missed
> Then apply the improved version.
- Always run Claude Code from inside a git repository — this gives you a safety net to revert any changes you don't like with `git checkout` or `git stash`, making experimentation risk-free.
- Invest 30 minutes writing a detailed CLAUDE.md file before your first real session. Every minute spent defining your coding standards and project context saves hours of prompt correction later.
- Use the phrase 'explain your reasoning before making changes' in complex prompts — this forces Claude Code to output its plan first, letting you catch misunderstandings before any files are modified.
- For large refactoring tasks, ask Claude Code to 'list all files that will need to change' as a first step. Review this list before proceeding — it reveals the scope of the change and catches unintended side effects early.
- Combine Claude Code with your existing CLI tools by asking it to run commands and interpret results. For example: 'Run eslint on the entire src/ directory and fix all auto-fixable errors, then list the errors that require manual attention.'
In this guide, you have learned how to install and authenticate Claude Code, configure it with a CLAUDE.md file tailored to your project, and effectively invoke its core skill categories including file editing, testing, git operations, debugging, and documentation. You have seen how to chain multiple skills together for complex autonomous workflows, run Claude Code in headless mode for CI/CD automation, and iterate on prompts to improve skill output quality. The key insight is that Claude Code's skills are not rigid commands — they are capabilities shaped by the context you provide. The more specific your prompts, the richer your CLAUDE.md, and the more you lean into multi-skill workflows, the more value you extract from the tool. As a next step, try building one complete feature end-to-end using Claude Code as your pair programmer: write the implementation, the tests, and the documentation in a single session. You will be surprised how quickly a well-directed AI assistant can accelerate your development velocity while still keeping you firmly in control of every decision.