A comprehensive ESLint plugin that integrates CSpell spell checking capabilities directly into the ESLint workflow, enabling developers to catch spelling errors in code comments, string literals, and documentation during the linting process.
npm install --save-dev @cspell/eslint-pluginUsing recommended configuration:
import cspellESLintPluginRecommended from '@cspell/eslint-plugin/recommended';
export default [
// other configs
cspellESLintPluginRecommended,
// other configs
];Using configs import:
import cspellConfigs from '@cspell/eslint-plugin/configs';
export default [
// other configs
cspellConfigs.recommended,
// other configs
];Using plugin import:
import cspellPlugin from '@cspell/eslint-plugin';
export default [
// other configs
{
plugins: { '@cspell': cspellPlugin },
rules: {
'@cspell/spellchecker': ['warn', {}]
}
},
// other configs
];{
"extends": ["plugin:@cspell/recommended"]
}import {
Options,
defaultOptions,
defineCSpellConfig,
defineCSpellPluginOptions
} from '@cspell/eslint-plugin';// eslint.config.js
import cspellPlugin from '@cspell/eslint-plugin';
export default [
{
plugins: { '@cspell': cspellPlugin },
rules: {
'@cspell/spellchecker': ['warn', {
checkComments: true,
checkStrings: true,
checkIdentifiers: true,
checkStringTemplates: true,
checkJSXText: true,
numSuggestions: 8,
generateSuggestions: true,
autoFix: false
}]
}
}
];// eslint.config.js
import cspellPlugin from '@cspell/eslint-plugin';
export default [
{
plugins: { '@cspell': cspellPlugin },
rules: {
'@cspell/spellchecker': ['warn', {
cspell: {
words: ['customword', 'mycompany', 'specialterm'],
dictionaries: ['custom-dict'],
dictionaryDefinitions: [
{
name: 'custom-dict',
path: './custom-dictionary.txt',
description: 'Custom company dictionary'
}
]
}
}]
}
}
];The CSpell ESLint plugin is built around several key components:
spellchecker rule that handles all spell checking functionalityCore plugin setup and configuration options for integrating spell checking into ESLint workflows.
interface Options {
numSuggestions: number;
generateSuggestions: boolean;
autoFix: boolean;
debugMode?: boolean;
ignoreImports?: boolean;
ignoreImportProperties?: boolean;
checkIdentifiers?: boolean;
checkStrings?: boolean;
checkStringTemplates?: boolean;
checkJSXText?: boolean;
checkComments?: boolean;
configFile?: string;
cspell?: CSpellOptions;
cspellOptionsRoot?: string | URL;
customWordListFile?: CustomWordListFilePath | CustomWordListFile;
checkScope?: ScopeSelectorList;
}The spell checking rule implementation that performs the actual linting and provides suggestions.
const rules: { spellchecker: Rule.RuleModule };
const configs: {
recommended: ESLint.ConfigData;
'recommended-legacy': ESLint.ConfigData;
debug: ESLint.ConfigData;
'debug-legacy': ESLint.ConfigData;
};
const plugin: ESLint.Plugin;Configuration options for the underlying CSpell spell checking engine.
interface CSpellOptions {
allowCompoundWords?: boolean;
caseSensitive?: boolean;
dictionaries?: string[];
enabled?: boolean;
flagWords?: string[];
ignoreWords?: string[];
ignoreRegExpList?: string[];
includeRegExpList?: string[];
import?: string[];
language?: string;
words?: string[];
dictionaryDefinitions?: DictionaryDefinition[];
}Utility functions for defining configuration objects with proper type safety.
function defineCSpellPluginOptions(options: Partial<Options>): Partial<Options>;
function defineCSpellConfig(cfg: CSpellOptions): CSpellOptions;interface CustomWordListFile {
path: CustomWordListFilePath;
}
type CustomWordListFilePath = string;
type ScopeSelector = string;
type ScopeSelectorEntry = [ScopeSelector, boolean];
type ScopeSelectorList = ScopeSelectorEntry[];
interface DictionaryDefinition {
name: string;
description?: string;
path?: string;
words?: string[];
flagWords?: string[];
ignoreWords?: string[];
suggestWords?: string[];
supportNonStrictSearches?: boolean;
}
interface Issue {
start: number;
end: number;
word: string;
severity: 'Forbidden' | 'Unknown' | 'Hint';
suggestions: Suggestions;
nodeType: NodeType;
node: ASTNode | undefined;
}
interface SpellCheckResults {
issues: Issue[];
errors?: Error[];
}
interface ExtendedSuggestion {
word: string;
isPreferred?: boolean;
wordAdjustedToMatchCase?: string;
}
type Suggestions = ExtendedSuggestion[] | undefined;
type ASTNode = Readonly<(Node | Comment | JSXText) & { parent?: Node }>;
type NodeType = ASTNode['type'];
interface JSXText extends Omit<Literal, 'type'> {
type: 'JSXText';
}
type RequiredOptions = Required<Pick<Options, Exclude<keyof Options, 'debugMode'>>> & Pick<Options, 'debugMode'>;
type WorkerOptions = RequiredOptions & { cwd: string };
// From ESTree and ESLint type definitions
interface Node {
type: string;
[key: string]: any;
}
interface Comment {
type: 'Line' | 'Block';
value: string;
start: number;
end: number;
}
interface Literal {
type: 'Literal';
value: string | boolean | null | number | RegExp | bigint;
raw: string;
}
const defaultOptions: Options;