How to Create Category Plugins in TSSLint to Group and Organize Rules

Create category plugins in TSSLint by importing createCategoryPlugin from @tsslint/config, defining a mapping of minimatch patterns to ts.DiagnosticCategory values, and including the plugin in your tsslint.config.ts to dynamically remap rule severities across your entire linting pipeline.

TSSLint, maintained in the johnsoncodehk/tsslint repository, provides a lightweight but powerful plugin system that lets you transform diagnostics after they are generated. When you create category plugins, you can batch-categorize related rules—such as treating all stylistic checks as suggestions or security issues as errors—without touching individual rule source code.

What Are Category Plugins?

A category plugin is a specialized TSSLint plugin that implements the Plugin interface defined in packages/types/index.ts (lines 24-33). Unlike rule plugins that generate diagnostics, category plugins consume diagnostics through the resolveDiagnostics hook and remap their category property to Error, Warning, Suggestion, or Message. This post-processing step allows you to organize rules into logical groups based on severity, making CLI output cleaner and filtering more predictable.

How Category Plugins Work

The Factory Function and Configuration

The core implementation lives in packages/config/lib/plugins/category.ts (lines 6-34). The exported create function (re-exported as createCategoryPlugin in packages/config/index.ts, lines 1-4) accepts a configuration object where:

  • Keys are minimatch glob patterns matching rule IDs or diagnostic codes (e.g., no-*, react/*).
  • Values are ts.DiagnosticCategory enum values (e.g., ts.DiagnosticCategory.Warning).
  • An optional source parameter defaults to "tsslint" and filters which diagnostics to process.

Pattern Matching and Caching

For each diagnostic whose source matches the configured value, the plugin stringifies the diagnostic code and tests it against the pattern map using the minimatch library. To optimize performance, the implementation maintains a matchCache that stores lookup results, avoiding redundant glob evaluations for repeated diagnostic codes.

Category Assignment

When a pattern matches, the plugin overwrites the diagnostic's category property with the user-specified value. The modified diagnostics array then flows back to the CLI or other downstream plugins, which render the updated severity levels.

Step-by-Step Guide to Creating Category Plugins

1. Import the Factory

Import the helper from the public API. This resolves to the re-export in packages/config/index.ts.

import { createCategoryPlugin } from '@tsslint/config';
import * as ts from 'typescript';

2. Define Your Category Mapping

Create an object that maps glob patterns to TypeScript diagnostic categories. Use standard minimatch syntax for flexible rule grouping.

const categoryMap = {
  // All console-related rules become warnings
  'no-console*': ts.DiagnosticCategory.Warning,
  // Any rule prefixed with "react/" is treated as an error
  'react/*': ts.DiagnosticCategory.Error,
  // Stylistic prefer-* rules appear as suggestions
  'prefer-*': ts.DiagnosticCategory.Suggestion,
  // Catch-all for info-level messages
  'tslint/*': ts.DiagnosticCategory.Message,
};

3. Instantiate the Plugin

Call createCategoryPlugin with your mapping. You can optionally pass a custom source string as the second argument if you need to process diagnostics from specific tools.

const myCategoryPlugin = createCategoryPlugin(categoryMap, 'tsslint');

4. Add to Your TSSLint Configuration

Include the plugin in your tsslint.config.ts file within the plugins array of defineConfig.

import { defineConfig, createCategoryPlugin } from '@tsslint/config';
import * as ts from 'typescript';
import NoConsoleRule from './rules/noConsoleRule';
import NoEvalRule from './rules/noEvalRule';

export default defineConfig({
  plugins: [
    // Category plugin remaps severities dynamically
    createCategoryPlugin({
      'no-console*': ts.DiagnosticCategory.Warning,
      'no-eval': ts.DiagnosticCategory.Error,
      'prefer-*': ts.DiagnosticCategory.Suggestion,
    }),
    // Add other plugins (ignore, custom formatters, etc.)
  ],
  rules: {
    'no-console': NoConsoleRule,
    'no-eval': NoEvalRule,
    // Additional rule definitions...
  },
});

5. Run TSSLint

Execute the CLI. Diagnostics emitted by matched rules now appear with your assigned categories, and the CLI respects these severities when filtering output.

npx tsslint src/**/*.ts

Advanced Pattern Matching Techniques

Because the category plugin uses minimatch under the hood, you can leverage full glob syntax in your patterns:

  • no-* matches no-console, no-debugger, no-eval.
  • react/* matches any rule in the react namespace.
  • **/security/* matches rules nested in any security subdirectory.
  • ? matches single characters, useful for versioned rule sets.

Patterns are evaluated in the order they are defined in your configuration object, and the first match wins. Place more specific patterns before generic wildcards to ensure correct categorization.

Summary

  • Category plugins intercept diagnostics after rule execution via the resolveDiagnostics hook defined in packages/types/index.ts.
  • The createCategoryPlugin factory, located in packages/config/lib/plugins/category.ts, accepts minimatch patterns and ts.DiagnosticCategory values to remap severities.
  • A built-in matchCache optimizes performance by avoiding redundant pattern matching for repeated diagnostic codes.
  • You import the helper from @tsslint/config, define your pattern-to-category map, and include the plugin in tsslint.config.ts to organize rules dynamically.

Frequently Asked Questions

What glob patterns are supported when I create category plugins?

TSSLint uses the minimatch library for pattern matching, supporting standard glob syntax including * (wildcards), ? (single character), **/ (any directory depth), and braces for expansion. This allows flexible groupings like no-* for all "no-" prefixed rules or react/* for entire rule namespaces.

Can I limit category plugins to diagnostics from specific sources?

Yes. The createCategoryPlugin factory accepts an optional second source parameter that defaults to "tsslint". By passing a different string (e.g., "eslint"), you can restrict the plugin to only remapping diagnostics that originated from that specific tool, leaving others unchanged.

How does the category plugin handle performance for large codebases?

The implementation in packages/config/lib/plugins/category.ts maintains a matchCache object that stores the result of pattern lookups keyed by diagnostic code. When the same rule fires multiple times, the plugin retrieves the cached category assignment instead of re-running minimatch comparisons, significantly reducing overhead in large projects.

Where is the category plugin defined in the TSSLint source code?

The primary logic resides in packages/config/lib/plugins/category.ts (lines 6-34), which exports the create function. This is re-exported as createCategoryPlugin in packages/config/index.ts (lines 1-4) for public consumption. The plugin implements the Plugin interface contract defined in packages/types/index.ts (lines 24-33).

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →