@shinyaz

How I Reduced My CLAUDE.md by 83% Using Claude Code's Skills System

Table of Contents

Challenge

After months of using Claude Code, my CLAUDE.md file had ballooned to 355 lines. Detailed project descriptions, content guidelines, testing procedures — I had crammed everything in there. The result? Claude started missing important instructions, buried under all that noise.

My previous post covered how to write a CLAUDE.md, but this one tackles the opposite problem — how to shrink it. It might seem contradictory, but a carefully written CLAUDE.md that grows too large actually undermines its own purpose of improving AI accuracy. Here's the problem and its concrete solution.

The Problem: Wasting Context Window

Claude Code's biggest constraint is the context window. Every conversation, file read, and command output accumulates here. And LLM performance degrades as the context fills up.

Why does this matter? CLAUDE.md is automatically loaded every time Claude Code starts a session. That means a 355-line CLAUDE.md consumes precious context on every single session start. The longer the conversation goes, the more this initial cost compounds.

My bloated CLAUDE.md looked like this:

## Content Writing
 
### Common Conventions
 
**Frontmatter:**
 
- `title` — Specific and outcome-oriented
- `description` — 80–200 chars, conveys unique value
- `date` — YYYY-MM-DD format
- `published` — true/false
- `tags` — lowercase, hyphenated technology names
 
### Blog Posts (`content/posts/{en,ja}/`)
 
**Goal:** Concrete, scannable, genuinely useful posts...
[200+ more lines...]

While these detailed instructions seemed useful, they actually caused:

  • 355 lines consuming context every session
  • Important rules getting lost in noise
  • Claude frequently ignoring instructions

The third issue was the most damaging. When a critical rule like "Use Server Components by default" is buried after 200 lines of content creation guidelines, Claude sometimes misses it entirely. It's the same phenomenon as humans skipping over important notes buried deep in a manual.

The Solution: Skills System

According to Claude Code's best practices documentation:

For each line ask: "Would removing this cause Claude to make a mistake?" If not, delete it.

So I moved detailed procedures to skills and kept only essential information in CLAUDE.md.

Skills are Markdown files placed in the .claude/skills/ directory that can be invoked with slash commands like /skill-name. While CLAUDE.md is a "configuration file that's always loaded," skills are "procedure manuals invoked only when needed." This distinction is what makes all the difference for context efficiency.

Implemented Skills Structure

.claude/skills/
├── post-guide/       # Blog post writing guide & creation
├── fix-lint/         # Auto-fix linting errors
├── sync-i18n/        # Check bilingual content sync
├── debug-build/      # Troubleshoot build errors
├── run-tests/        # Run appropriate tests
├── add-mdx-component/# Add MDX components
└── README.md         # Skills documentation

Each skill lives in its own directory with a SKILL.md file containing the procedure. The directory name becomes the command name — so a post-guide/ directory is invoked with /post-guide.

Example Skill: /post-guide

---
name: post-guide
description: Blog post writing guidelines and creation workflow. Loaded when creating, editing, or reviewing blog posts in content/posts/.
---
 
Blog post writing guide: $ARGUMENTS
 
## Writing Principles
 
These principles apply to both new and existing blog posts.
 
### Title (Principle 1)
 
- Include the technology name
- Lead with the outcome, not the topic
  [Writing principles continue...]
 
## New Post Creation Workflow
 
When explicitly invoked with `/post-guide`, follow these steps to create a new post.
 
1. **Determine post basics**
   - Date format: YYYY-MM-DD
   - Slug: kebab-case (lowercase with hyphens)
     [Creation steps continue...]

This example does not set disable-model-invocation. When Claude Code judges the task to be related to blog post editing, the Writing Principles section is automatically loaded as guidance. When explicitly invoked with /post-guide nextjs-performance-tips, the full file including the New Post Creation Workflow is executed.

The key structural choice is placing the guidance section at the top of the file. When the SKILL.md body loads at Stage 2 of progressive disclosure, the writing principles come first. The creation workflow sits at the bottom, so during auto-loading the skill functions as "knowledge," while during explicit invocation it functions as "procedure."

For skills like /fix-lint that only contain side effects such as file changes or build execution, set disable-model-invocation: true so they only run when explicitly invoked.

$ARGUMENTS is a placeholder that expands to whatever text the user types after the command. When you enter /post-guide nextjs-performance-tips, $ARGUMENTS becomes nextjs-performance-tips, and Claude executes the procedure based on that input.

Result: 59-Line CLAUDE.md

The optimized CLAUDE.md is now just 59 lines. What remains is only "information Claude needs to know every time" — command lists, skill references, and project-specific constraints. All detailed procedures have moved to skills, loaded only when needed:

# CLAUDE.md
 
**Language rule:** Think in English internally.
Always respond to the user in Japanese.
 
## Commands
 
npm run dev # Dev server
npm run build # Production build
npm test # Unit tests
[...]
 
## Skills
 
Use `/skill-name` for common tasks:
 
- `/post-guide` — Blog post writing guide
- `/fix-lint` — Fix linting errors
- `/sync-i18n` — Check bilingual content
  [...]
 
## Critical Rules
 
- Server Components by default
- TypeScript strict mode
- Tailwind only
- Build must pass
  [...]

Impact: Dramatic Improvements

This optimization delivered the following improvements. Most importantly, it wasn't just about reducing line count — Claude's response quality visibly improved.

1. Better Context Efficiency

  • 355 lines → 59 lines (83% reduction)
  • Important instructions no longer buried
  • Longer sessions now possible

2. Standardized Workflows

  • /post-guide creates blog posts instantly
  • /fix-lint auto-fixes all linting issues
  • Team shares identical workflows

3. Improved Maintainability

  • Update each skill independently
  • Personal settings via local skills (.local/)
  • Version control with Git

Best Practices Checklist

Deciding what to keep in CLAUDE.md versus what to move to skills can feel tricky at first. The table below shows the criteria I actually used. The underlying principle is simple: "Don't write what Claude can figure out by reading the code":

✅ Include❌ Exclude
Commands Claude can't inferThings Claude understands from code
Non-default code style rulesStandard language conventions
Project-specific settingsDetailed API documentation
Critical constraints and rulesGeneric best practices

What I Removed

Theory alone makes it hard to decide, so here are concrete examples of what I moved and why. The common thread is that all of these are "detailed procedures," not "rules." A 50-line test procedure can be replaced with the one-line rule "tests must pass":

Before (in CLAUDE.md)After (in skills)
Detailed test procedures (50 lines)/run-tests skill
Content creation guide (80 lines)/post-guide skill
Debug procedures (40 lines)/debug-build skill
MDX component guide (30 lines)/add-mdx-component skill

Real-World Usage

Invoking skills is straightforward. Simply type /skill-name during a Claude Code conversation, and the corresponding SKILL.md is loaded, with Claude following its procedures. You can also pass arguments — /post-guide nextjs-performance-tips tells Claude exactly what to create.

Running Skills

# Create new blog post
/post-guide nextjs-performance-tips
 
# Auto-fix linting errors
/fix-lint
 
# Debug build errors
/debug-build
 
# Check bilingual content sync
/sync-i18n

When to Create a Skill

Creating too many skills makes management cumbersome. Too few, and your CLAUDE.md bloats again. Here are the criteria I use to decide whether something deserves its own skill:

Create a skill for:

  • Tasks repeated 3+ times
  • Procedures with 5+ steps
  • Team-shared workflows
  • Complex, error-prone processes

Keep in CLAUDE.md:

  • Project-specific constraints
  • Always-applied rules
  • Basic command lists
  • Settings Claude can't infer

Implementation Tips

Here's how to introduce the skills system in your own project. The key is to proceed incrementally rather than attempting a massive migration.

1. Start by Measuring

Check your current CLAUDE.md line count. Over 100 lines means significant optimization potential. Under 50, and you may be fine for now:

wc -l CLAUDE.md  # Check current line count

2. Create Skills

Just create a directory and place a SKILL.md inside — no complex configuration needed:

mkdir -p .claude/skills/your-skill
cat > .claude/skills/your-skill/SKILL.md << 'EOF'
---
name: your-skill
description: What this skill does
disable-model-invocation: true  # If has side effects
---
Your workflow steps here...
EOF

3. Configure .gitignore

Commit team-shared skills to Git, but manage personal customizations with a .local/ suffix and add them to .gitignore. This maintains team standards while accommodating individual preferences:

echo ".claude/skills/*.local/" >> .gitignore
echo "CLAUDE.local.md" >> .gitignore

Troubleshooting

Here are common issues you might encounter when adopting the skills system, all based on my own experience.

Q: Skill not recognized

A: Check that skill name matches directory name. Verify the name: field is set correctly.

Q: When to use disable-model-invocation?

A: Set to true for side effects like file changes, builds, or test runs. Skip for read-only operations.

Q: CLAUDE.md still feels long

A: Ask "Would Claude work correctly without this?" for each line. Aim for under 50 lines.

Addendum: Skills vs. Slash Commands

This article uses the term "skills" for everything placed in .claude/skills/, but Claude Code actually has two distinct mechanisms: slash commands (.claude/commands/) and skills (.claude/skills/), with different design philosophies. Practical Claude Code (Gijutsu-Hyoron) clarifies the distinction as follows:

PropertySlash CommandsSkills
Location.claude/commands/*.md.claude/skills/*/SKILL.md
InvocationUser explicitly runs /commandClaude Code auto-loads based on relevance
ScopeActive only during command executionActive throughout the session
PurposeDefine workflows (what, in what order)Teach tool usage and reasoning
File structureSingle .md fileDirectory structure (with supporting files)

Skills like /fix-lint that set disable-model-invocation: true and require explicit invocation are closer to "slash commands" in the book's classification. On the other hand, /post-guide does not set disable-model-invocation, so its writing principles auto-load when editing posts — this is the native skill pattern. The mechanism that powers this auto-loading is progressive disclosure.

How Progressive Disclosure Works

CLAUDE.md is loaded in full into the context window every session. Even at 59 lines that's a few hundred tokens; at the pre-optimization 355 lines it was several thousand. Skills, on the other hand, load only what's needed in three stages.

Stage 1: Metadata only (~100 tokens per skill)

At session start, Claude Code reads only the name and description of every skill. It uses this information to judge which skills are relevant to the current task.

# Only this part is read initially
 
---
 
name: typescript-conventions
description: TypeScript coding conventions. Defines type definitions, naming rules, and error handling patterns
 
---

This means the quality of your description determines whether the skill gets loaded. For a task like "writing TypeScript code," the description above clearly signals relevance. A vague description like "coding conventions" might not trigger loading when it should.

Stage 2: SKILL.md body loaded (under 5,000 tokens)

Only skills judged relevant have their SKILL.md body loaded. If you have 10 skills but are doing TypeScript work, only 1-2 TypeScript-related skills get fully loaded. The remaining 8 consume only their Stage 1 metadata (~800 tokens total).

Stage 3: Supporting files loaded (only when needed)

Skills can have a directory structure, so SKILL.md can reference supporting files — templates, code examples, detailed guides. These load only when SKILL.md instructions call for them.

.claude/skills/typescript-conventions/
├── SKILL.md              # Loaded at Stage 2
├── guides/
│   ├── naming.md         # Naming convention details (on demand)
│   └── error-handling.md # Error pattern catalog (on demand)
└── examples/
    └── patterns.ts       # Code examples (on demand)

Context Consumption: CLAUDE.md vs. Skills

Here's why progressive disclosure matters, illustrated with concrete token numbers.

Suppose you have four rule sets: TypeScript conventions (500 tokens), React conventions (400 tokens), testing conventions (600 tokens), and security conventions (300 tokens).

All in CLAUDE.md: 1,800 tokens consumed every session. Even when you're only writing TypeScript, the React, testing, and security rules occupy context the entire time.

Separated into skills: Metadata alone costs 400 tokens (100 × 4). When writing TypeScript, only 500 additional tokens load. Total: 900 tokens — a 50% context savings. As your task changes, the loaded skills automatically switch too.

Designing Guidance-Type Skills

To take advantage of progressive disclosure, guidance-type skills need intentional design.

Write specific descriptions: The description is Claude Code's only signal for relevance at Stage 1. Instead of a vague "coding conventions," write "TypeScript coding conventions. Defines type definitions, naming rules, and error handling patterns" — making it clear which tasks should trigger loading.

Keep SKILL.md under 5,000 tokens: If the Stage 2 body is too large, progressive disclosure loses its advantage. Put details in supporting files and keep SKILL.md as a summary with references.

Narrow the scope: Packing multiple concerns into one skill means it loads for unrelated tasks too. Separate "TypeScript conventions" and "React conventions" into distinct skills so only the relevant one loads.

Workflow vs. Guidance Types

This project places everything under .claude/skills/, but being intentional about the usage pattern makes the design clearer:

  • Workflow type (/fix-lint, /debug-build, etc.): Set disable-model-invocation: true and invoke explicitly. Functions like a slash command.
  • Guidance type (coding conventions, architecture rules, etc.): Don't set disable-model-invocation, letting Claude Code auto-load based on task context. This is the native skill pattern.

Whether disable-model-invocation: true is set effectively becomes the dividing line between these two roles.

Summary

  • Separate always-loaded rules from on-demand procedures — CLAUDE.md holds constraints; skills hold step-by-step workflows. This single distinction drives the biggest accuracy gains.
  • Use disable-model-invocation: true to control side effects — Any skill that creates files, runs builds, or modifies state should require explicit invocation.
  • Design with workflow vs. guidance types in mind — Explicitly invoked procedure manuals and auto-loaded knowledge bases require different design approaches. The disable-model-invocation flag is the dividing line.
  • Aim for under 50 lines in CLAUDE.md — If you can't remove a line without Claude making mistakes, keep it. Everything else belongs in a skill.

Next Steps

To further automate this optimization process and enable continuous improvement, check out Building a Self-Improving System with Meta-Skills.


Reference: Claude Code Best Practices

Series articles:

  1. Maximizing AI Coding Assistants with CLAUDE.md
  2. How I Reduced My CLAUDE.md by 83% Using Claude Code's Skills System (this article)
  3. Claude Code Meta-Skills: Creating a Self-Improving System with Skills that Manage Skills
  4. Scaling Claude Code Meta-Skills Across Teams: Maximizing AI-Assisted Development Productivity Organization-Wide

Share this post

Shinya Tahara

Shinya Tahara

Solutions Architect @ AWS

I'm a Solutions Architect at AWS, providing technical guidance primarily to financial industry customers. I share learnings about cloud architecture and AI/ML on this blog.

Related Posts