oxlint-plugin-cspell
v0.1.0
Published
High-performance AST-aware CSpell plugin for Oxlint and ESLint
Maintainers
Readme
oxlint-plugin-cspell
High-performance, AST-aware CSpell checking for Oxlint and ESLint. It preserves
the JavaScript/TypeScript selection semantics of @cspell/eslint-plugin 9.6.0
while avoiding that plugin's second recursive AST walk.
Development and measured compatibility currently target Oxlint 1.73.0, CSpell 9.6.0, and Node.js 20 or newer.
How it works
@oxlint/pluginscreateOncevisitors collect onlyIdentifier,Literal,TemplateElement, andJSXTextranges while Oxlint performs its own walk.- Comments come from the parser's existing comment list; the plugin never walks a JavaScript/TypeScript AST recursively.
- One persistent synchronous worker owns configuration and validator caches.
- CSpell configuration search is cached per directory and resolved settings are
passed with
noConfigSearch. - A safe fast path reuses finalized validators only when the configuration has
no filename overrides and the document has no in-document CSpell directives.
It falls back to a full
DocumentValidatorpass whenever it finds an issue, preserving suggestions, preferred fixes, and diagnostics. - If every AST source option is disabled,
before()returnsfalseand Oxlint skips traversal for the rule.
createOnce itself is not the immediate speedup in Oxlint 1.73.0. The measured
gain comes from eliminating walkTree(ast), reducing per-file preparation, and
reusing validation results. The API choice positions the plugin for Oxlint's
future optimized visitor transport.
Installation
Install the plugin as a development dependency:
pnpm add -D oxlint-plugin-cspellOxlint configuration
Use an alias to keep existing @cspell/spellchecker rule names and inline
suppression comments unchanged:
{
"jsPlugins": [
{
"name": "@cspell",
"specifier": "oxlint-plugin-cspell"
}
],
"rules": {
"@cspell/spellchecker": [
"warn",
{
"ignoreImports": true,
"ignoreImportProperties": true,
"checkIdentifiers": true,
"checkStrings": false,
"checkStringTemplates": true,
"checkJSXText": true,
"checkComments": true,
"configFile": "./cspell.json",
"autoFix": false
}
]
}
}Without the alias, the natural rule name is cspell/spellchecker.
Inline Oxlint suppression remains supported:
// oxlint-disable-next-line @cspell/spellchecker
const protocolSpecificName = value;ESLint flat configuration
import cspell from 'oxlint-plugin-cspell';
export default [
{
plugins: { cspell },
rules: {
'cspell/spellchecker': ['warn', { configFile: './cspell.json' }],
},
},
];Options and behavior
The plugin supports the upstream options and behavior for:
- identifiers, quoted strings, template elements, JSX text, and comments;
- imports, re-exports,
require()sources, and imported member properties; checkScope, including the upstream JSON/YAML default scopes under ESLint;configFile, inlinecspellsettings, imported configuration, custom dictionaries, andcustomWordListFile;all,simple,typos, andflaggedreport levels;- exact locations, severity, suggestions, preferred fixes, and
autoFix; - in-document CSpell directives and inline Oxlint disable directives.
customParserTraversal is the only new option. Its default, auto, performs a
compatibility-only recursive walk when an ESLint custom parser exposes JSON or
YAML node types. always forces that fallback and never disables it. Normal
JavaScript/TypeScript files never take this path.
Known platform limitation
Oxlint 1.73.0 does not support custom parsers or custom file formats. Therefore
JSON/YAML checkScope behavior is available when this plugin runs under ESLint,
but cannot be reproduced by Oxlint itself. This is an Oxlint platform limit,
not a semantic substitution; the plugin does not route source through the
generic CSpell CLI text parser.
CSpell ignorePaths and enabled do not trigger an additional plugin-level
skip because upstream checks explicitly selected AST ranges even when those
document flags would exclude a CLI document. Changing that would break parity.
Verification
pnpm lint
pnpm typecheck
pnpm test:unit
pnpm test:parity
pnpm test:oxlint
pnpm benchmark:fixtures
pnpm parity:app --app /path/to/app-monorepo
pnpm benchmark:app --app /path/to/app-monorepo --runs 3The parity matrix compares normalized message, range, severity, suggestions,
and fixes against @cspell/eslint-plugin. The Oxlint subprocess test verifies
plugin aliasing and inline suppression. Full app results are in
reports/parity.md and
reports/benchmark-app.md.
Current app-monorepo result
On the cloned codex/try-oxlint-upgrade branch at commit
170f14e671edbe69ef13155bb0ff98859820ecec, full diagnostics are exact. Three
fresh, interleaved Apple M4 Pro runs produced these medians:
| Mode | Median |
| --- | ---: |
| No CSpell | 42.45s |
| @cspell/eslint-plugin 9.6.0 | 67.34s |
| oxlint-plugin-cspell | 59.45s |
The ≤65s acceptance target and strict <60s stretch target are both met. These macOS numbers must not be presented as Windows measurements; the supplied Windows reference remains 80s total and 49.5s without CSpell. The no-CSpell result remains the theoretical floor—dictionary validation is still required, so the full CSpell contribution is not recoverable.
License
MIT
