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
minimatchglob patterns matching rule IDs or diagnostic codes (e.g.,no-*,react/*). - Values are
ts.DiagnosticCategoryenum values (e.g.,ts.DiagnosticCategory.Warning). - An optional
sourceparameter 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-*matchesno-console,no-debugger,no-eval.react/*matches any rule in thereactnamespace.**/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
resolveDiagnosticshook defined inpackages/types/index.ts. - The
createCategoryPluginfactory, located inpackages/config/lib/plugins/category.ts, accepts minimatch patterns andts.DiagnosticCategoryvalues to remap severities. - A built-in
matchCacheoptimizes 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 intsslint.config.tsto 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →