From f83e06eaf9fc80d28c44e6e5b4a7e54ace899a67 Mon Sep 17 00:00:00 2001 From: Shayan Rais Date: Fri, 30 Jan 2026 19:42:21 +0500 Subject: [PATCH] Claude skills in larger mono repos --- CLAUDE.md | 1 + .../claude-skills-for-larger-mono-repos.md | 151 ++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 reports/claude-skills-for-larger-mono-repos.md diff --git a/CLAUDE.md b/CLAUDE.md index 442e26a..97a5f13 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -93,3 +93,4 @@ From experience with this repository: - `reports/claude-in-chrome-v-chrome-devtools-mcp.md`: Browser automation MCP comparison (Playwright vs Chrome DevTools vs Claude in Chrome) - `reports/claude-md-for-larger-mono-repos.md`: CLAUDE.md loading behavior in monorepos (ancestor vs descendant loading) +- `reports/claude-skills-for-larger-mono-repos.md`: Skills discovery and loading behavior in monorepos (static vs dynamic discovery) diff --git a/reports/claude-skills-for-larger-mono-repos.md b/reports/claude-skills-for-larger-mono-repos.md new file mode 100644 index 0000000..813af8c --- /dev/null +++ b/reports/claude-skills-for-larger-mono-repos.md @@ -0,0 +1,151 @@ +# Understanding Claude Skills Discovery in Large Monorepos + +When working with Claude Code in a monorepo, understanding how skills are discovered and loaded into context is crucial for organizing your project-specific capabilities effectively. + +## Important Difference from CLAUDE.md + +**Skills do NOT have the same loading behavior as CLAUDE.md files.** While CLAUDE.md files walk UP the directory tree (ancestor loading), skills use a different discovery mechanism focused on nested directories within your project. + +## How Skills Are Discovered + +### 1. Standard Skill Locations + +Skills are loaded from these fixed locations based on scope: + +| Location | Path | Applies to | +|----------|------|------------| +| Enterprise | Managed settings | All users in organization | +| Personal | `~/.claude/skills//SKILL.md` | All your projects | +| Project | `.claude/skills//SKILL.md` | This project only | +| Plugin | `/skills//SKILL.md` | Where plugin is enabled | + +### 2. Automatic Discovery from Nested Directories + +When you work with files in subdirectories, Claude Code automatically discovers skills from nested `.claude/skills/` directories. For example, if you're editing a file in `packages/frontend/`, Claude Code also looks for skills in `packages/frontend/.claude/skills/`. + +This supports monorepo setups where packages have their own skills. + +## Example Monorepo Structure + +Consider a typical monorepo with separate packages: + +``` +/mymonorepo/ +├── .claude/ +│ └── skills/ +│ └── shared-conventions/SKILL.md # Project-level skill +├── packages/ +│ ├── frontend/ +│ │ ├── .claude/ +│ │ │ └── skills/ +│ │ │ └── react-patterns/SKILL.md # Frontend-specific skill +│ │ └── src/ +│ │ └── App.tsx +│ ├── backend/ +│ │ ├── .claude/ +│ │ │ └── skills/ +│ │ │ └── api-design/SKILL.md # Backend-specific skill +│ │ └── src/ +│ └── shared/ +│ ├── .claude/ +│ │ └── skills/ +│ │ └── utils-patterns/SKILL.md # Shared utilities skill +│ └── src/ +``` + +## Scenario 1: Just Started Claude at Root (No Files Edited Yet) + +When you run Claude Code from `/mymonorepo/` and haven't edited any files yet: + +```bash +cd /mymonorepo +claude +# Just started - no files edited yet +``` + +| Skill | In Context? | Reason | +|-------|-------------|--------| +| `shared-conventions` | **Yes** | Project-level skill in root `.claude/skills/` | +| `react-patterns` | **No** | Not discovered - haven't worked with files in `packages/frontend/` | +| `api-design` | **No** | Not discovered - haven't worked with files in `packages/backend/` | +| `utils-patterns` | **No** | Not discovered - haven't worked with files in `packages/shared/` | + +## Scenario 2: After Editing Files in a Package + +After you ask Claude to edit `packages/frontend/src/App.tsx`: + +| Skill | In Context? | Reason | +|-------|-------------|--------| +| `shared-conventions` | **Yes** | Project-level skill in root `.claude/skills/` | +| `react-patterns` | **Yes** | Discovered when editing files in `packages/frontend/` | +| `api-design` | **No** | Still not discovered - haven't worked with files in `packages/backend/` | +| `utils-patterns` | **No** | Still not discovered - haven't worked with files in `packages/shared/` | + +**Key insight**: Nested skills are discovered **on-demand** when you work with files in those directories. They are not preloaded at session start. + +## Key Behavior: Description vs Full Content + +Skill descriptions are loaded into context so Claude knows what's available, but **full skill content only loads when invoked**. This is an important optimization: + +- **Descriptions**: Always in context (within character budget) +- **Full content**: Loaded on-demand when skill is invoked + +> Note: Subagents with preloaded skills work differently - the full skill content is injected at startup. + +## Priority Order (When Skills Share Names) + +When skills share the same name across levels, higher-priority locations win: + +| Priority | Location | Scope | +|----------|----------|-------| +| 1 (highest) | Enterprise | Organization-wide | +| 2 | Personal (`~/.claude/skills/`) | All your projects | +| 3 (lowest) | Project (`.claude/skills/`) | This project only | + +Plugin skills use a `plugin-name:skill-name` namespace, so they cannot conflict with other levels. + +## Why This Design Works for Monorepos + +- **Package-specific skills stay isolated** - Frontend developers working in `packages/frontend/` get frontend-specific skills without backend skills cluttering context. + +- **Automatic discovery reduces configuration** - No need to explicitly register package-level skills; they're discovered when you work in those directories. + +- **Context is optimized** - Only skill descriptions load initially, and nested skills are discovered on-demand. + +- **Teams can maintain their own skills** - Each package team can define skills specific to their domain without coordinating with other teams. + +## Character Budget Considerations + +Skill descriptions are loaded into context up to a character budget (default 15,000 characters). In large monorepos with many packages and skills, you may hit this limit. + +- Run `/context` to check for warnings about excluded skills +- Set `SLASH_COMMAND_TOOL_CHAR_BUDGET` environment variable to increase the limit + +## Best Practices + +1. **Put shared workflows in root `.claude/skills/`** - Repository-wide conventions, commit workflows, and shared patterns. + +2. **Put package-specific skills in package `.claude/skills/`** - Framework-specific patterns, component conventions, testing utilities unique to that package. + +3. **Use `disable-model-invocation: true` for dangerous skills** - Deployment or destructive skills should require explicit user invocation. + +4. **Keep skill descriptions concise** - Descriptions are always in context (up to the character budget), so verbose descriptions waste context space. + +5. **Use namespacing in skill names** - Consider prefixing with package names (e.g., `frontend-review`, `backend-deploy`) to avoid confusion. + +## Comparison: Skills vs CLAUDE.md Loading + +| Behavior | CLAUDE.md | Skills | +|----------|-----------|--------| +| Ancestor loading (UP directory tree) | Yes | No | +| Nested/descendant discovery (DOWN directory tree) | Yes (lazy) | Yes (automatic discovery) | +| Global location | `~/.claude/CLAUDE.md` | `~/.claude/skills/` | +| Project location | `.claude/` or repo root | `.claude/skills/` | +| Content loading | Full content | Description only (full on invocation) | + +--- + +## Sources + +- [Claude Code Documentation - Extend Claude with Skills](https://code.claude.com/docs/en/skills) +- [Claude Code Documentation - Automatic Discovery from Nested Directories](https://code.claude.com/docs/en/skills#automatic-discovery-from-nested-directories)