Monorepo Support
claudelint provides full support for monorepo projects with workspace detection and configuration inheritance.
File Discovery
claudelint recursively discovers Claude Code configuration files throughout your project tree. CLAUDE.md files in subdirectories (e.g., packages/api/CLAUDE.md, src/CLAUDE.md) are automatically found and validated. Skills in nested .claude/skills/ directories are also discovered, matching Claude Code's on-demand subdirectory skill loading.
For the complete file discovery table and glob patterns, see File Discovery.
Quick Start
1. Config Inheritance
Share configuration across packages using the extends field:
{
"extends": "./base-config.json",
"rules": {
"claude-md-size": "warn"
}
}2. Workspace Validation
Validate specific packages or all packages in your monorepo:
claudelint check-all --workspace my-package
claudelint check-all --workspacesConfiguration Inheritance
Basic Usage
Create a base configuration that child packages can extend:
{
"extends": "../.claudelintrc.json",
"rules": {
"skill-missing-version": "error"
}
}Supported Formats
Relative paths:
{
"extends": "../../.claudelintrc.json"
}Node modules packages:
{
"extends": "claudelint-config-standard"
}{
"extends": "@company/claudelint-config"
}Multiple extends:
{
"extends": ["./base.json", "./strict.json"]
}Merge Behavior
When extending configs, claudelint merges configurations in this order:
- Base config (first in extends array)
- Additional extended configs (in order)
- Current config (overrides everything)
Each field type merges differently:
| Field | Strategy |
|---|---|
rules | Deep merged (child can override specific rules) |
overrides | Arrays concatenated (all overrides apply) |
ignorePatterns | Arrays concatenated and deduplicated |
output | Child completely replaces parent |
| Scalars | Child value wins |
Example Monorepo Structure
monorepo/
├── CLAUDE.md # Root project context
├── .claudelintrc.json # Root config
├── pnpm-workspace.yaml
├── packages/
│ ├── app-1/
│ │ ├── CLAUDE.md # Package-specific context
│ │ └── .claudelintrc.json # Extends root
│ └── app-2/
│ ├── CLAUDE.md # Package-specific context
│ └── .claudelintrc.json # Extends root
└── libs/
└── shared/
├── CLAUDE.md # Package-specific context
└── .claudelintrc.json # Extends root{
"rules": {
"claude-md-size": "warn",
"skill-missing-version": "error"
},
"ignorePatterns": [
"node_modules/**",
"dist/**"
]
}{
"extends": "../../.claudelintrc.json"
}{
"extends": "../../.claudelintrc.json",
"rules": {
"claude-md-size": "warn"
}
}Workspace Detection
claudelint automatically detects monorepo workspaces from:
- pnpm-workspace.yaml (pnpm)
- package.json workspaces field (npm/Yarn)
Supported Package Managers
packages:
- 'packages/*'
- 'apps/*'{
"workspaces": [
"packages/*",
"apps/*"
]
}{
"workspaces": {
"packages": [
"packages/*",
"apps/*"
]
}
}CLI Flags
Validate specific package:
claudelint check-all --workspace my-packageThis finds the workspace package with directory name my-package and runs validation only for that package.
Validate all packages:
claudelint check-all --workspacesThis runs validation for every package in the workspace and aggregates results.
Troubleshooting
No workspace detected
Problem: claudelint can't find a workspace configuration in the current directory.
Workspace detection looks for pnpm-workspace.yaml or a workspaces field in package.json.
Solution: Run the command from your monorepo root where the workspace config file exists.
Package not found
Problem: --workspace flag references a package name that doesn't match any workspace.
The error output lists available packages for reference.
Solution: Use the exact directory name of the package (shown in the "Available packages" list in the error output).
Extended config not found
Problem: A .claudelintrc.json uses extends to reference a config file that doesn't exist.
Solution: Check that the relative path is correct and the target file exists on disk.
Circular dependency
Problem: Config extends chain creates a cycle (A extends B, B extends A).
Solution: Remove the circular reference so the extends chain forms a tree.
Migration Guide
Upgrading existing monorepos:
packages/
├── app-1/.claudelintrc.json (full config)
├── app-2/.claudelintrc.json (full config)
└── shared/.claudelintrc.json (full config).claudelintrc.json (shared rules)
packages/
├── app-1/.claudelintrc.json (extends root)
├── app-2/.claudelintrc.json (extends root)
└── shared/.claudelintrc.json (extends root)Steps:
Create root .claudelintrc.json with common rules
Update package configs to extend root:
json{ "extends": "../../.claudelintrc.json" }Keep only package-specific overrides in child configs
Test with
claudelint check-all --workspaces
Backward compatibility: All existing configs continue to work without changes. The extends field is optional, workspaces are auto-detected, and there are no breaking changes to existing functionality.
Best Practices
- Keep root config minimal - only shared rules
- Use extends for consistency - avoid duplicating rules
- Override sparingly - only when packages truly differ
- Test with --workspaces - catch issues across all packages
- Version shared configs - treat them like dependencies
- Document overrides - explain why packages differ