New to Claude Skills? Learn how to install them →

Cn8n-io on GitHub

Create Community Node Lint Rule

Free

Streamline ESLint rule creation for n8n community nodes.

by n8n-io200.1k stars on n8n-io/n8n
1 views
Updated Aug 10, 2026
Get this skill

Free · Opens the source repo

What Create Community Node Lint Rule does

The Create Community Node Lint Rule skill provides a structured approach for developers working with the n8n platform to add new ESLint rules specifically for the @n8n/eslint-plugin-community-nodes package. This skill is essential for those looking to enforce coding standards and best practices within their community nodes, ensuring code quality and consistency across the n8n ecosystem. By following the outlined steps, developers can create custom lint rules that detect various issues such as missing properties or incorrect patterns in their code.

The skill guides users through the entire process of rule creation, starting with understanding the specific requirements of the rule, including its application scope and severity level. It includes detailed instructions on how to implement the rule in TypeScript, providing a template that can be easily modified to suit specific needs. The provided code snippets illustrate how to utilize existing AST helpers to streamline the development of lint rules, making it easier to identify and report issues in the codebase.

In addition to implementation, the skill emphasizes the importance of testing the newly created rules. It offers a framework for writing tests that validate both valid and invalid cases, ensuring that the rules function as intended. This focus on testing is crucial for maintaining the reliability of lint rules, especially as the codebase evolves. Finally, the skill includes steps for registering the new rule within the n8n ecosystem, ensuring that it is properly integrated and available for use.

Overall, this skill is tailored for developers and contributors to the n8n project who aim to enhance code quality through custom linting rules, making it a valuable resource for maintaining high standards in community node development.

When to use it

Use this skill when you need to add new ESLint rules for community nodes in n8n, especially when enforcing coding standards or improving code quality.

When not to use it

This skill is not suitable for general ESLint rule creation outside of the n8n community node context or for users unfamiliar with TypeScript and ESLint.

What you can build with it

Adding a New Lint Rule

When developing a new community node, use this skill to create a corresponding ESLint rule that enforces specific coding standards.

Improving Code Quality

Utilize this skill to implement lint rules that help catch common mistakes in community nodes, enhancing overall code quality.

Testing Custom Rules

After creating a new lint rule, follow the testing guidelines provided in this skill to ensure your rule behaves correctly.

How to install Create Community Node Lint Rule

View source

1. Install with the skills CLI

npx skills add n8n-io/n8n/create-community-node-lint-rule --agent claude-code

2. Or install it manually

Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.

Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs

Inside SKILL.md

Written by n8n-io

Create Community Node Lint Rule

Guide for adding new ESLint rules to packages/@n8n/eslint-plugin-community-nodes/.

All paths below are relative to packages/@n8n/eslint-plugin-community-nodes/.

Step 1: Understand the Rule

Before writing code, clarify:

  • What does the rule detect? (missing property, wrong pattern, bad value)
  • Where does it apply? (.node.ts files, credential classes, both)
  • Severity: error (must fix) or warn (should fix)?
  • Fixable? Can it be auto-fixed safely, or only suggest?
  • Scope: Both recommended configs, or exclude from recommendedWithoutN8nCloudSupport?

Step 2: Implement the Rule

Create src/rules/<rule-name>.ts:

import { AST_NODE_TYPES } from '@typescript-eslint/utils';

import {
  isNodeTypeClass,       // or isCredentialTypeClass
  findClassProperty,
  findObjectProperty,
  createRule,
} from '../utils/index.js';

export const YourRuleNameRule = createRule({
  name: 'rule-name',
  meta: {
    type: 'problem',  // or 'suggestion'
    docs: {
      description: 'One-line description of what the rule enforces',
    },
    messages: {
      messageId: 'Human-readable message. Use {{placeholder}} for dynamic data.',
    },
    fixable: 'code',     // omit if not auto-fixable
    hasSuggestions: true, // omit if no suggestions
    schema: [],           // add options schema if configurable
  },
  defaultOptions: [],
  create(context) {
    return {
      ClassDeclaration(node) {
        if (!isNodeTypeClass(node)) return;

        const descriptionProperty = findClassProperty(node, 'description');
        if (!descriptionProperty) return;

        const descriptionValue = descriptionProperty.value;
        if (descriptionValue?.type !== AST_NODE_TYPES.ObjectExpression) return;

        // Rule logic here — use findObjectProperty(), getLiteralValue(), etc.

        context.report({
          node: targetNode,
          messageId: 'messageId',
          data: { /* template vars */ },
          fix(fixer) {
            return fixer.replaceText(targetNode, 'replacement');
          },
        });
      },
    };
  },
});

Naming: Export as PascalCaseRule (e.g. MissingPairedItemRule). The name field is kebab-case.

Available AST helpers — see reference.md for the full catalog of ast-utils and file-utils exports.

Step 3: Write Tests

Create src/rules/<rule-name>.test.ts:

import { RuleTester } from '@typescript-eslint/rule-tester';

import { YourRuleNameRule } from './rule-name.js';

const ruleTester = new RuleTester();

// Helper to generate test code — keeps test cases readable
function createNodeCode(/* parameterize the varying parts */): string {
  return `
import type { INodeType, INodeTypeDescription } from 'n8n-workflow';

export class TestNode implements INodeType {
  description: INodeTypeDescription = {
    displayName: 'Test Node',
    name: 'testNode',
    group: ['input'],
    version: 1,
    description: 'A test node',
    defaults: { name: 'Test Node' },
    inputs: [],
    outputs: [],
    properties: [],
  };
}`;
}

ruleTester.run('rule-name', YourRuleNameRule, {
  valid: [
    { name: 'class that does not implement INodeType', code: '...' },
    { name: 'node with correct pattern', code: createNodeCode(/* correct */) },
  ],
  invalid: [
    {
      name: 'descriptive case name',
      code: createNodeCode(/* incorrect */),
      errors: [{ messageId: 'messageId', data: { /* expected template vars */ } }],
      output: createNodeCode(/* expected after fix */),  // or `output: null` if no fix
    },
  ],
});

Test guidelines:

  • Always test that non-INodeType classes are skipped (valid case)
  • Test both the error message and the fixed output for fixable rules
  • For rules with options, test each option combination
  • For rules using filesystem, mock with vi.mock('../utils/file-utils.js')
  • For suggestion-only rules, use errors: [{ messageId, suggestions: [...] }]

Step 4: Register the Rule

4a. Add to src/rules/index.ts

import { YourRuleNameRule } from './rule-name.js';

// Add to the rules object:
export const rules = {
  // ... existing rules
  'rule-name': YourRuleNameRule,
} satisfies Record<string, AnyRuleModule>;

4b. Add to src/plugin.ts configs

Add to both config objects (unless the rule depends on n8n cloud features):

'@n8n/community-nodes/rule-name': 'error',  // or 'warn'
  • Use error for rules that catch bugs or required patterns
  • Use warn for style/convention rules (like options-sorted-alphabetically)
  • If the rule uses no-restricted-globals or no-restricted-imports patterns, only add to recommended (not recommendedWithoutN8nCloudSupport)

Step 5: Write Documentation

Create docs/rules/<rule-name>.md:

# Description of what the rule does (`@n8n/community-nodes/rule-name`)

<!-- end auto-generated rule header -->

## Rule Details

Explain why this rule exists and what problem it prevents.

## Examples

### Incorrect

\`\`\`typescript
// code that triggers the rule
\`\`\`

### Correct

\`\`\`typescript
// code that passes the rule
\`\`\`

The header above <!-- end auto-generated rule header --> will be regenerated by pnpm build:docs. Write a reasonable first version — it gets overwritten.

Step 6: Verify

Run from packages/@n8n/eslint-plugin-community-nodes/:

pushd packages/@n8n/eslint-plugin-community-nodes
pnpm test <rule-name>.test.ts   # tests pass
pnpm typecheck                   # types are clean
pnpm build                       # compiles
pnpm build:docs                  # regenerates doc headers and README table
pnpm lint:docs                   # docs match schema
popd

Checklist

  • Rule file: src/rules/<rule-name>.ts
  • Test file: src/rules/<rule-name>.test.ts
  • Registered in src/rules/index.ts
  • Added to configs in src/plugin.ts
  • Doc file: docs/rules/<rule-name>.md
  • README table updated via pnpm build:docs
  • All verification commands pass

Frequently asked questions about Create Community Node Lint Rule

Similar skills