A full-fledged JavaScript and JSX parser for cspell. It gives you control over which parts of your code get spell checked, from comments and strings to function and variable names. It also lets you skip module imports and other code that isn't under your control.
This plugin leverages the JavaScript parsers exported from
@cspell/parser-typescript.
npm install --save-dev @cspell/parser-javascriptThe quickest way to get started is to import the recommended settings, which registers the plugin and selects its parsers for every supported file type:
cspell.config.jsonc
For more control - for example, to apply it to only some file types, or alongside other settings - wire the plugin in yourself and choose the language IDs to use it for:
cspell.config.jsonc
{
"import": ["@cspell/parser-javascript"],
"languageSettings": [
{ "languageId": "javascript", "parser": "javascript" },
{ "languageId": "javascriptreact", "parser": "javascriptreact" },
],
}The plugin has one parser per file type, named after it. Where Recommended is yes, recommended enables
the named parser for files with that Language ID:
| Language ID | Parser Name | Recommended |
|---|---|---|
| javascript | javascript | yes |
| javascriptreact | javascriptreact | yes |
Both parsers read JSX, whatever the file is called.
By default, identifiers, strings, comments, and JSX text are spell checked, and the rest of the code isn't.
Use customizePlugin to change what gets checked. For example, to check only line comments and doc
comments:
cspell.config.ts or cspell.config.mjs
import { customizePlugin } from '@cspell/parser-javascript/plugin';
// Check only line comments and doc comments.
export default customizePlugin({
tags: { '*': false, comment: true, 'comment.block': false, 'comment.block.doc': true },
}).defineConfig();NOTE:
Keys in
tagsare matched hierarchically against the tags below. For example, the keycommentalso matches the more specificcomment.block.doc, unless a more specific key overrides it. A key can also use*as a wildcard, such ascomment.*, or a bare*for everything not otherwise matched.
Calling customizePlugin gives you a customized copy of the plugin. Call defineConfig() on it to get a
complete cspell config, or keep adjusting it first.
Each file type has its own parser, so each one can have its own filter. For example, to check only the comments in JSX files, and keep the defaults for JavaScript files:
cspell.config.ts or cspell.config.mjs
import { customizePlugin } from '@cspell/parser-javascript/plugin';
// JSX files: check only comments.
// JavaScript files: keep the defaults.
export default customizePlugin().filterTags('javascriptreact', { '*': false, comment: true }).defineConfig();Each part of a file gets its most specific tag plus the more general ones above it. For example, a doc
comment is tagged comment.block.doc, comment.block, and comment, so a filter can use whichever level it
needs.
| Tag | Meaning |
|---|---|
string |
A string literal (fallback for a quote style that's neither ' nor ") |
string.singleQuote |
A '...' string literal |
string.doubleQuote |
A "..." string literal |
string.module |
A module specifier string literal (fallback for a quote style that's neither ' nor ") |
string.singleQuote.module |
A '...' string literal that is also a module specifier |
string.doubleQuote.module |
A "..." string literal that is also a module specifier |
string.templateLiteral |
A literal text fragment of a template string (`...`), excluding ${...} substitutions |
module |
Any module specifier string |
module.specifier |
Any module specifier string (same as module, for a more specific filter) |
module.specifier.literal |
The module specifier string of an import/export ... from statement or a dynamic import('...') call |
comment |
Any comment |
comment.line |
A // line comment |
comment.block |
A /* ... */ block comment |
comment.block.doc |
A /** ... */ doc comment |
identifier |
Any identifier |
identifier.variable |
A variable name |
identifier.property |
An object or class property name |
identifier.privateProperty |
A #private class property name |
identifier.type |
A type name |
identifier.shorthandProperty |
A shorthand object property name (the foo in { foo }) |
identifier.label |
A statement label |
identifier.importBinding |
A renamed import alias, default import name, or namespace import name |
identifier.exportBinding |
A renamed export alias (export { x as y }) |
jsx |
Any JSX text (JSX attribute strings and names keep their string and identifier tags) |
jsx.text |
The text between JSX tags, such as the Hello in <p>Hello</p> |
code |
Everything else (off by default) |
In JSX text, character references are decoded, so Café is checked as Café. This covers the named
references JSX supports, as well as decimal (é) and hex (é) references. An unknown reference,
such as &bogus;, is left as it is.
By default, keywords, punctuation, numbers, and everything else tagged code aren't spell checked. To check
them too:
customizePlugin({ tags: { code: true } }).defineConfig();-
JSX in a
.jsfile is read as JSX. VS Code gives.jsfiles thejavascriptfile type even when they contain JSX, and thejavascriptparser handles it. -
Package names aren't spell checked. The package name in an
import,export ... from,import(...), orrequire(...), such as'lodash','@scope/pkg', or'node:fs', isn't spelling you wrote. A relative path such as'./utils.js'is still checked. -
Names that come from an imported package aren't spell checked. That includes a named import's original name and properties read from an imported value. A name you chose, such as a renamed import's alias or a default import's name, is checked.
-
A local name that reuses an import's name is checked. A variable or parameter that shadows an import is your own name, so it's checked where it's in scope.
Use customizePlugin(options) to control which parts of a file get spell checked, based on the tags
the parsers give each part. The filter applies to every parser in the plugin.
interface CustomizePluginOptions {
/** Chooses which tagged segments every parser keeps. */
tags: TagFilterOptions;
}Everything including code
const option = { tags: { '*': true } };Everything except code
const option = { tags: { '*': true, code: false } };Only comments
const option = { tags: { '*': false, comment: true } };Turn off identifier.property
const option = { tags: { 'identifier.property': false } };Use TagFilterOptions to set the filter criteria for the text sent to the spell checker.
The values are inherited hierarchically:
comment: falsealso impliescomment.lineisfalseunless overridden by'comment.line': true
Wildcards:
*wildcards are weak matches. A more specific match will win.
/**
* A tag name, or a `*`-wildcard pattern matching one.
*/
type TagPattern = string;
interface TagFilterOptions {
/**
* The default filter setting for any tag not otherwise matched.
* @default true
*/
'*'?: boolean | undefined;
/**
* Filter setting for the specific tag or wildcard pattern.
*
* If not specified, the default (`'*'`) will be used.
*/
[tag: TagPattern]: boolean | undefined;
}- Uses
@cspell/parser-typescript, which runs on WebAssembly, so it doesn't need a native compiler toolchain to install. identifier.typenever appears, since JavaScript has no type names.
| Tool | Version |
|---|---|
| cspell | >=10.0.0 |
| Code Spell Checker | >=4.4.0 |
If our spell checkers and plugins save you time, please consider supporting their development.
Please show your support through one of the following sites:
Copyright (c) 2026 Street Side Software
Brought to you by Street Side Software




{ "import": ["@cspell/parser-javascript/recommended"], }