Skip to content

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:

json
{
  "extends": "./base-config.json",
  "rules": {
    "claude-md-size": "warn"
  }
}

2. Workspace Validation ​

Validate specific packages or all packages in your monorepo:

bash
claudelint check-all --workspace my-package

claudelint check-all --workspaces

Configuration Inheritance ​

Basic Usage ​

Create a base configuration that child packages can extend:

json
{
  "extends": "../.claudelintrc.json",
  "rules": {
    "skill-missing-version": "error"
  }
}

Supported Formats ​

Relative paths:

json
{
  "extends": "../../.claudelintrc.json"
}

Node modules packages:

json
{
  "extends": "claudelint-config-standard"
}
json
{
  "extends": "@company/claudelint-config"
}

Multiple extends:

json
{
  "extends": ["./base.json", "./strict.json"]
}

Merge Behavior ​

When extending configs, claudelint merges configurations in this order:

  1. Base config (first in extends array)
  2. Additional extended configs (in order)
  3. Current config (overrides everything)

Each field type merges differently:

FieldStrategy
rulesDeep merged (child can override specific rules)
overridesArrays concatenated (all overrides apply)
ignorePatternsArrays concatenated and deduplicated
outputChild completely replaces parent
ScalarsChild value wins

Example Monorepo Structure ​

text
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
json
{
  "rules": {
    "claude-md-size": "warn",
    "skill-missing-version": "error"
  },
  "ignorePatterns": [
    "node_modules/**",
    "dist/**"
  ]
}
json
{
  "extends": "../../.claudelintrc.json"
}
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 ​

yaml
packages:
  - 'packages/*'
  - 'apps/*'
json
{
  "workspaces": [
    "packages/*",
    "apps/*"
  ]
}
json
{
  "workspaces": {
    "packages": [
      "packages/*",
      "apps/*"
    ]
  }
}

CLI Flags ​

Validate specific package:

bash
claudelint check-all --workspace my-package

This finds the workspace package with directory name my-package and runs validation only for that package.

Validate all packages:

bash
claudelint check-all --workspaces

This 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:

text
packages/
├── app-1/.claudelintrc.json  (full config)
├── app-2/.claudelintrc.json  (full config)
└── shared/.claudelintrc.json (full config)
text
.claudelintrc.json              (shared rules)
packages/
├── app-1/.claudelintrc.json  (extends root)
├── app-2/.claudelintrc.json  (extends root)
└── shared/.claudelintrc.json (extends root)

Steps:

  1. Create root .claudelintrc.json with common rules

  2. Update package configs to extend root:

    json
    {
      "extends": "../../.claudelintrc.json"
    }
  3. Keep only package-specific overrides in child configs

  4. 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 ​

  1. Keep root config minimal - only shared rules
  2. Use extends for consistency - avoid duplicating rules
  3. Override sparingly - only when packages truly differ
  4. Test with --workspaces - catch issues across all packages
  5. Version shared configs - treat them like dependencies
  6. Document overrides - explain why packages differ

FAQ ​