no-irregular-whitespace

Disallow whitespace characters other than the ordinary space, tab and line break

error by default

A no-break space (U+00A0) looks exactly like a space, and a zero-width space (U+200B) looks like nothing. They get into a file when you paste from a web page or a chat, or press Option+Space on a Mac. The code may still run, but a search for total = price no longer finds the line, and diffs show changes that nobody can see.

Reported characters: U+000B, U+000C, U+0085, U+00A0, U+1680, U+180E, U+2000 to U+200B, U+2028, U+2029, U+202F, U+205F, U+3000 and U+FEFF. A byte order mark at the very start of the file is fine.

Only code is checked by default. In strings, template literals, comments, regular expressions and JSX text these characters are usually there on purpose: French puts a no-break space before : and €, and Japanese text uses the full-width space U+3000.

This rule is on by default.

Configure#

On by default as an error. To turn it off:

bunfig.toml
[lint.rules]
"no-irregular-whitespace" = "off" # or "warn"

Every option, set to its default:

bunfig.toml
[lint.rules]
"no-irregular-whitespace" = ["error", {
  skipStrings = true,
  skipComments = true,
  skipRegExps = true,
  skipTemplates = true,
  skipJSXText = true,
}]

Examples#

Reported. The character after = is a no-break space:

example.js1 problem
const total = price * quantity;

Not reported, with an ordinary space:

example.jsNo problems
const total = price * quantity;

Not reported either. These no-break spaces are part of the text:

example.jsxNo problems
// At most 10 kg.
const weight = "10 kg";
const price = <p>Prix : 10 €</p>;

Options#

Each option allows the characters in one kind of place.

OptionDefaultWhat it does
skipStringstrueAllow them in string literals.
skipCommentstrueAllow them in comments.
skipRegExpstrueAllow them in regular expression literals.
skipTemplatestrueAllow them in template literals.
skipJSXTexttrueAllow them in JSX text.

With an ESLint config file the defaults are ESLint's: only skipStrings is true.

Every example below has a no-break space between 10 and kg.

example.jswith { "skipStrings": false }1 problem
const weight = "10 kg";
example.jswith { "skipComments": false, "skipTemplates": false }2 problems
// At most 10 kg.
const weight = `10 kg`;
example.jswith { "skipComments": true, "skipTemplates": true }No problems
// At most 10 kg.
const weight = `10 kg`;
example.jsxwith { "skipJSXText": false, "skipRegExps": false }2 problems
const label = <span>10 kg</span>;
const pattern = /10 kg/;
example.jsxwith { "skipJSXText": true, "skipRegExps": true }No problems
const label = <span>10 kg</span>;
const pattern = /10 kg/;