Skip to content

Custom Rules Guide

claudelint allows you to define custom validation rules to extend the built-in rule set with your own team-specific or project-specific requirements. For contributing built-in rules, see the Contributing Guide.

Quick Start

  1. Create a .claudelint/rules/ directory in your project root
  2. Add a custom rule file (.ts or .js)
  3. Export a rule object that implements the Rule interface
  4. Run claudelint check-all to load and execute your custom rules

Example custom rule that validates SKILL.md files have cross-references:

typescript
import type { Rule } from 'claude-code-lint';
import { hasHeading } from 'claude-code-lint/utils';

export const rule: Rule = {
  meta: {
    id: 'require-skill-see-also',
    name: 'Require Skill See Also',
    description: 'SKILL.md must have a ## See Also section for cross-referencing related skills',
    category: 'Skills',
    severity: 'warn',
    fixable: false,
  },

  validate: async (context) => {
    if (!context.filePath.endsWith('SKILL.md')) {
      return;
    }

    if (!hasHeading(context.fileContent, 'See Also', 2)) {
      context.report({
        message: 'Missing ## See Also section',
        line: 1,
        fix: 'Add a ## See Also section linking to related skills',
      });
    }
  },
};

Directory Structure

Custom rules are automatically discovered in .claudelint/rules/:

text
your-project/
├── .claudelint/
│   └── rules/
│       ├── team-rule.ts
│       ├── project-rule.ts
│       └── conventions/
│           └── naming-rule.ts
├── CLAUDE.md
└── .claudelintrc.json
  • Rules can be organized in subdirectories
  • Both .ts and .js files are supported
  • .d.ts, .test.ts, and .spec.ts files are automatically excluded

Valid Categories

Custom rules must use one of the built-in categories. The category determines which validator executes your rule.

CategoryDescription
CLAUDE.mdRules targeting CLAUDE.md configuration files
SkillsRules for skill definitions (SKILL.md)
SettingsRules for settings files
HooksRules for hook configurations
MCPRules for MCP server configurations
PluginRules for plugin manifests
CommandsRules for command definitions
AgentsRules for agent definitions
OutputStylesRules for output style configurations
LSPRules for LSP server configurations

Examples

See the Custom Rule Examples page for three practical examples covering pattern matching, auto-fix, and configurable options. All examples are real rules from claudelint's own .claudelint/rules/ directory.

Configuration

Custom rules can be configured in .claudelintrc.json just like built-in rules:

json
{
  "rules": {
    "require-skill-see-also": "warn",
    "no-user-paths": "error",
    "normalize-code-fences": "off"
  }
}

Testing

Create test cases using a collectIssues helper. See the dogfood rule tests for a working example:

typescript
import { rule } from './.claudelint/rules/my-rule';

async function collectIssues(rule, filePath, fileContent) {
  const issues = [];
  await rule.validate({
    filePath,
    fileContent,
    options: {},
    report: (issue) => issues.push(issue),
  });
  return issues;
}

const issues = await collectIssues(rule, '/test/SKILL.md', 'content missing required section');
expect(issues).toHaveLength(1);

Helper Library

claudelint provides utility functions for common validation tasks like heading detection, pattern matching, frontmatter parsing, and file system operations. See the Helper Library Reference for the complete API.

See Also