Skip to content
Back to Writing

Why Most CLAUDE.md Files Are Too Big: A Better Multi-Stack Claude Code Setup

Byte Smith · · 8 min read

Most CLAUDE.md files in the wild are a single massive document covering every stack, convention, and edge case the team has ever discussed. The content itself is usually fine. The problem is the delivery. Dumping 400 or more lines of instructions into every Claude Code session wastes context and confuses priorities, because Claude loads all of it regardless of what you are actually working on.

This matters more than it seems. LLMs have finite context windows, and every token of instruction competes with the code Claude is actually reading and editing. If you work across multiple stacks, a monolithic CLAUDE.md means Claude is reading your Docker conventions while you are fixing a React component, and absorbing your SQL guidance while you are debugging a Python endpoint. A modular, two-tier setup fixes that by loading only the rules relevant to what you are touching right now. The result is faster, more accurate, and easier to maintain.

The monolithic CLAUDE.md problem

A typical monolithic CLAUDE.md starts small. You add a few coding standards, some git conventions, maybe a note about your preferred testing approach. Then the project grows. Someone adds Laravel rules. Someone else adds React patterns. The DevOps engineer drops in Docker and CI/CD guidance. The database team adds SQL conventions. Six months later, you have a 500-line file covering six stacks, and nobody wants to prune it because they are afraid of breaking something.

The costs are real:

  • Context window waste. Claude loads every instruction every session, even when you are only editing files in one stack. A Python-only session still loads Laravel, React, Docker, and SQL rules.
  • Signal dilution. Important rules get buried in noise. When everything is equally prominent, nothing stands out.
  • Merge conflicts. Five developers editing one file means constant conflicts, especially in active projects.
  • Staleness. Old rules linger because nobody knows if removing them will cause problems. The file only grows.

This is the same problem software engineering solved decades ago with the god object. The fix is the same too: split by responsibility, load on demand.

The solution: modular two-tier rules

The claude-code-vscode-multistack-starter replaces the monolithic approach with a two-tier architecture. The first tier covers universal concerns that apply every session. The second tier covers stack-specific rules that load only when Claude touches matching files.

Here is what the directory structure looks like:

.claude/
  rules/
    common.md          # unconditional - always loaded
    testing.md         # unconditional
    git.md             # unconditional
    security.md        # unconditional
    laravel.md         # conditional - paths frontmatter
    react-next.md      # conditional
    python-fastapi.md  # conditional
    node-express.md    # conditional
    docker-devops.md   # conditional
    sql.md             # conditional
  agents/
    laravel-architect.md
    react-ui.md
    python-api.md
    node-backend.md
    devops-reviewer.md
    sql-investigator.md
  hooks/
    session-start.sh
    post-edit-check.sh
  prompts/
    bugfix.md
    refactor.md
    code-review.md
    onboarding.md
  settings.json
CLAUDE.md
scripts/
  detect-stack.sh
  install-local.sh

Tier 1: Unconditional rules load every session. These are cross-cutting concerns that apply regardless of what files you are editing: baseline coding standards, testing philosophy, git conventions, and security guardrails. They have no paths frontmatter, so Claude always sees them.

Tier 2: Conditional stack rules load only when Claude reads or edits files matching specific glob patterns. This is a native Claude Code feature. Each rule file includes a paths block in its YAML frontmatter that tells Claude when to activate it.

For example, the Laravel rule file triggers only when you touch PHP files, routes, app code, migrations, or views:

---
paths:
  - "**/*.php"
  - "**/routes/**"
  - "**/app/**"
  - "**/database/migrations/**"
  - "**/resources/views/**"
---

The other stack rules follow the same pattern. React rules trigger on .tsx, .jsx, and next.config.*. Python rules trigger on .py and pyproject.toml. Node rules trigger on server.js, app.js, and middleware files. Docker rules trigger on Dockerfile and compose files. SQL rules trigger on .sql files and migration directories.

The practical difference is significant. A Python-only session loads about 80 lines of rules: the four unconditional files plus python-fastapi.md. A Laravel plus Docker session loads about 120 lines. Compare that to a monolithic file where every session loads 400 or more lines regardless of what you are doing.

What goes in CLAUDE.md versus rules files

With this setup, CLAUDE.md becomes a lightweight router instead of an encyclopedia. It describes the project at a high level, lists the active stacks, sets default behavior expectations, and imports the unconditional rules using the @ syntax.

Here is what the actual CLAUDE.md looks like:

# Claude Code Project Guide

This repository is a multi-stack starter configuration for Claude Code in VS Code.

## How this repo works

- **Unconditional rules** in `.claude/rules/` (common, testing, git, security)
  load every session.
- **Stack-specific rules** in `.claude/rules/` use `paths` frontmatter to load
  only when you touch matching files.
- **Subagents** in `.claude/agents/` handle focused tasks.
- **Hooks** in `.claude/settings.json` run automation on session start and
  after edits.
- **Prompts** in `.claude/prompts/` provide reusable workflow templates.

## Imported rules (always loaded)

@.claude/rules/common.md
@.claude/rules/testing.md
@.claude/rules/git.md
@.claude/rules/security.md

The rule of thumb is simple. If it applies to every session, make it an unconditional rule or put it directly in CLAUDE.md. If it only matters when touching certain files, add paths frontmatter and let Claude load it on demand.

Subagents for focused work

Subagents are specialized agents defined in .claude/agents/ with their own system prompts, tool access, and model selection. They are useful when a task benefits from focused expertise rather than general guidance.

The starter includes six agents, one per stack:

  • laravel-architect — Eloquent models, migrations, API resources, Form Requests, service patterns
  • react-ui — component architecture, state management, accessibility, styling
  • python-api — FastAPI endpoints, Pydantic models, async patterns
  • node-backend — Express middleware, error handling, route structure
  • devops-reviewer — Dockerfiles, CI/CD pipelines, infrastructure review
  • sql-investigator — query optimization, schema review, data analysis

Each agent has frontmatter that defines its capabilities. Here is the Laravel architect:

---
name: laravel-architect
description: Laravel architecture specialist for Eloquent models, migrations,
  API resources, Form Requests, service patterns, and routing.
tools: Read, Edit, Write, Bash, Grep, Glob
model: sonnet
maxTurns: 25
---

The key distinction between agents and rules is scope. Rules provide ambient guidance that shapes how Claude approaches code. Agents handle multi-step, focused tasks where you want a specialized perspective. Think of rules as coding standards and agents as specialist teammates you pull into a conversation.

Hooks for lightweight automation

The starter configures two hooks in .claude/settings.json that run automatically at specific lifecycle points:

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "startup",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/session-start.sh",
            "timeout": 30
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/post-edit-check.sh",
            "timeout": 60
          }
        ]
      }
    ]
  }
}

The SessionStart hook runs session-start.sh every time a new Claude session begins. It calls detect-stack.sh, which scans for marker files and outputs a JSON object listing the detected stacks:

{
  "stacks": ["laravel", "docker-devops", "sql"],
  "detected_at": "2026-04-01T12:00:00Z"
}

This gives Claude immediate context about the project structure without requiring the developer to explain it manually. The hook also checks for a missing .env file when .env.example exists.

The PostToolUse hook runs post-edit-check.sh after any Edit or Write operation. It reads the edited file path from the tool input, determines the file type, and runs a lightweight lint check: php -l for PHP, ruff check for Python, npx eslint for JavaScript and TypeScript, and a manual-review reminder for SQL files. These checks run automatically without interrupting the developer.

Results and benefits

The practical improvements from this setup show up immediately:

  • Leaner context. A single-stack session loads 50 to 80 lines of rules instead of 400 or more. That leaves more context for the code Claude is actually working on.
  • Better accuracy. Claude follows stack-specific patterns more reliably when they are not buried in unrelated instructions. Signal goes up, noise goes down.
  • Easier maintenance. Each stack owner edits their own rule file. The Laravel developer updates laravel.md, the frontend developer updates react-next.md, and nobody conflicts on a shared monolithic file.
  • Faster onboarding. New team members add their stack rules without touching shared files. The unconditional rules represent team-wide agreements that change less frequently.
  • Portable. The entire .claude/ directory copies cleanly between projects. The install script handles the transfer automatically.

How to try it

The starter is open source and ready to use. There are two ways to get started:

Option 1: Clone and install. Clone the repository and run the install script against an existing project:

git clone https://github.com/InkByteStudio/claude-code-vscode-multistack-starter.git
cd claude-code-vscode-multistack-starter
./scripts/install-local.sh /path/to/your/project

The script copies the .claude/ directory and CLAUDE.md into your project, makes hook scripts executable, and runs stack detection to show which stacks were found.

Option 2: Manual copy. Copy the .claude/ directory and CLAUDE.md into your project root. Remove the stack rules and agents you do not need.

Either way, the first thing to do after installing is customize. Delete stacks you do not use. Adjust the unconditional rules to match your team’s conventions. Add new stack rules for technologies the starter does not cover yet. The starter is a foundation, not a finished product.

Start building a better Claude Code setup

The core idea is straightforward. Stop dumping every rule into one file. Split by responsibility, load on demand, and let Claude focus on what matters for the current task. That principle applies whether you use this starter directly or build your own modular config from scratch.

For a hands-on walkthrough of building this setup from scratch, see the companion tutorial: Claude Code Setup in VS Code: Build a Better Multi-Stack CLAUDE.md Starter.

If you are evaluating Claude Code alongside other AI coding tools, this modular approach is worth comparing to how other tools handle configuration. Claude Code’s conditional rules via paths frontmatter give you a level of control that single-file configs in other tools cannot match. Teams already investing in AI coding agents and custom MCP servers will find that modular Claude Code configuration fits naturally into the same workflow.

For teams working on governance and security around agentic development, pair this setup with our guide to securing AI coding agent workflows and the agentic AI security playbook.