JavaScript stylistic rules for ESLint that enforce code formatting and style consistency without changing code logic.
—
Rules that prevent common stylistic issues and enforce consistent patterns across codebases.
Disallows unnecessary parentheses.
const noExtraParens: Rule.RuleModule;
// Rule options
type NoExtraParensOptions =
| 'all'
| 'functions'
| ['all' | 'functions', {
conditionalAssign?: boolean;
returnAssign?: boolean;
nestedBinaryExpressions?: boolean;
ignoreJSX?: 'none' | 'all' | 'single-line' | 'multi-line';
enforceForArrowConditionals?: boolean;
enforceForSequenceExpressions?: boolean;
enforceForNewInMemberExpressions?: boolean;
enforceForFunctionPrototypeMethods?: boolean;
}];Usage Examples:
// ✗ Bad - unnecessary parentheses
const result = (a + b);
if ((condition)) {
doSomething();
}
const func = (function() { return true; });
// ✓ Good - necessary parentheses only
const result = a + b;
if (condition) {
doSomething();
}
const func = function() { return true; };
// ✓ Good - parentheses needed for precedence
const result = (a + b) * c;
const condition = (x === 1) || (y === 2);
// ✓ Good with { conditionalAssign: false }
let result;
if ((result = getValue())) { // parens allowed for assignment
process(result);
}Configuration:
rules: {
'@stylistic/js/no-extra-parens': ['error', 'all', { ignoreJSX: 'all' }]
}Disallows unnecessary semicolons.
const noExtraSemi: Rule.RuleModule;
// No optionsUsage Examples:
// ✗ Bad - extra semicolons
function example() {
return true;;
}
const obj = {
name: 'John';
};
class Example {
method() {
return true;;
};
}
// ✓ Good - necessary semicolons only
function example() {
return true;
}
const obj = {
name: 'John'
};
class Example {
method() {
return true;
}
}Configuration:
rules: {
'@stylistic/js/no-extra-semi': 'error'
}Disallows mixed spaces and tabs for indentation.
const noMixedSpacesAndTabs: Rule.RuleModule;
// Rule options
type NoMixedSpacesAndTabsOptions = 'smart-tabs' | boolean;Usage Examples:
// ✗ Bad - mixing spaces and tabs
function example() {
⇥ return true; // spaces followed by tab
}
// ✓ Good - consistent spaces
function example() {
return true;
}
// ✓ Good - consistent tabs
function example() {
⇥ return true;
}
// ✓ Good with "smart-tabs" - tabs for indentation, spaces for alignment
function example() {
⇥ const items = [
⇥ 'apple', // tab for indent, spaces for alignment
⇥ 'banana'
⇥ ];
}Configuration:
rules: {
'@stylistic/js/no-mixed-spaces-and-tabs': 'error'
}Disallows trailing whitespace at the end of lines.
const noTrailingSpaces: Rule.RuleModule;
// Rule options
type NoTrailingSpacesOptions = {
skipBlankLines?: boolean;
ignoreComments?: boolean;
};Usage Examples:
// ✗ Bad - trailing spaces
const name = 'John';
const age = 30;
// ✓ Good - no trailing spaces
const name = 'John';
const age = 30;
// ✓ Good with skipBlankLines: true
const name = 'John';
// blank line with spaces OK
const age = 30;
// ✓ Good with ignoreComments: true
const name = 'John'; // comment with trailing spacesConfiguration:
rules: {
'@stylistic/js/no-trailing-spaces': ['error', { skipBlankLines: true }]
}Disallows multiple spaces.
const noMultiSpaces: Rule.RuleModule;
// Rule options
type NoMultiSpacesOptions = {
exceptions?: {
[nodeType: string]: boolean;
};
ignoreEOLComments?: boolean;
};Usage Examples:
// ✗ Bad - multiple spaces
const name = 'John';
if (condition && other) {
doSomething();
}
// ✓ Good - single spaces
const name = 'John';
if (condition && other) {
doSomething();
}
// ✓ Good with exceptions: { Property: true }
const obj = {
name : 'John', // multiple spaces allowed in properties
age : 30
};
// ✓ Good with ignoreEOLComments: true
const value = 1; // multiple spaces before EOL comment OKConfiguration:
rules: {
'@stylistic/js/no-multi-spaces': ['error', {
exceptions: { Property: true },
ignoreEOLComments: true
}]
}Disallows whitespace before properties.
const noWhitespaceBeforeProperty: Rule.RuleModule;
// No optionsUsage Examples:
// ✗ Bad - whitespace before property
const value = obj .property;
const result = user ['name'];
const method = obj .method();
// ✓ Good - no whitespace before property
const value = obj.property;
const result = user['name'];
const method = obj.method();
// Computed properties and method calls
const dynamic = obj[key];
const chained = obj.method().property;Configuration:
rules: {
'@stylistic/js/no-whitespace-before-property': 'error'
}Enforces a maximum line length.
const maxLen: Rule.RuleModule;
// Rule options
type MaxLenOptions =
| number
| {
code?: number;
tabWidth?: number;
comments?: number;
ignorePattern?: string;
ignoreComments?: boolean;
ignoreTrailingComments?: boolean;
ignoreUrls?: boolean;
ignoreStrings?: boolean;
ignoreTemplateLiterals?: boolean;
ignoreRegExpLiterals?: boolean;
};Usage Examples:
// ✗ Bad with code: 80
const veryLongVariableNameThatExceedsTheMaximumLineLengthAndShouldBeWrapped = 'value';
// ✓ Good with code: 80
const longVariableName = 'value';
const message = 'This is a shorter line that fits within the limit';
// ✓ Good with ignoreUrls: true
const url = 'https://this-is-a-very-long-url-that-would-normally-exceed-the-line-length-limit.com/path'; // URL ignored
// ✓ Good with ignoreStrings: true
const longString = 'This is a very long string that would normally exceed the line length limit but is ignored'; // String ignoredConfiguration:
rules: {
'@stylistic/js/max-len': ['error', {
code: 100,
tabWidth: 2,
ignoreUrls: true,
ignoreStrings: true,
ignoreTemplateLiterals: true
}]
}Enforces a maximum number of statements allowed per line.
const maxStatementsPerLine: Rule.RuleModule;
// Rule options
type MaxStatementsPerLineOptions = {
max?: number;
};Usage Examples:
// ✗ Bad with max: 1 (default)
const a = 1; const b = 2;
if (condition) doSomething(); return;
// ✓ Good with max: 1
const a = 1;
const b = 2;
if (condition) {
doSomething();
}
return;
// ✓ Good with max: 2
const a = 1; const b = 2; // two statements OKConfiguration:
rules: {
'@stylistic/js/max-statements-per-line': ['error', { max: 1 }]
}Disallows leading or trailing decimal points in numeric literals.
const noFloatingDecimal: Rule.RuleModule;
// No optionsUsage Examples:
// ✗ Bad - floating decimal points
const leading = .5;
const trailing = 2.;
// ✓ Good - complete decimal numbers
const leading = 0.5;
const trailing = 2.0;
const integer = 2;
const decimal = 1.5;Configuration:
rules: {
'@stylistic/js/no-floating-decimal': 'error'
}Enforces consistent brace style for blocks.
const braceStyle: Rule.RuleModule;
// Rule options
type BraceStyleOptions =
| '1tbs'
| 'stroustrup'
| 'allman'
| ['1tbs' | 'stroustrup' | 'allman', {
allowSingleLine?: boolean;
}];Usage Examples:
// ✓ Good with "1tbs" (default - One True Brace Style)
if (condition) {
doSomething();
} else {
doSomethingElse();
}
// ✓ Good with "stroustrup"
if (condition) {
doSomething();
}
else {
doSomethingElse();
}
// ✓ Good with "allman"
if (condition)
{
doSomething();
}
else
{
doSomethingElse();
}
// ✓ Good with allowSingleLine: true
if (condition) { doSomething(); }Configuration:
rules: {
'@stylistic/js/brace-style': ['error', '1tbs', { allowSingleLine: true }]
}rules: {
'@stylistic/js/no-extra-parens': ['error', 'all'],
'@stylistic/js/no-extra-semi': 'error',
'@stylistic/js/no-trailing-spaces': 'error',
'@stylistic/js/no-multi-spaces': 'error',
'@stylistic/js/max-len': ['error', { code: 80 }],
'@stylistic/js/max-statements-per-line': ['error', { max: 1 }]
}rules: {
'@stylistic/js/no-extra-semi': 'error',
'@stylistic/js/no-trailing-spaces': ['error', { skipBlankLines: true }],
'@stylistic/js/no-multi-spaces': ['error', { ignoreEOLComments: true }],
'@stylistic/js/max-len': ['error', {
code: 120,
ignoreUrls: true,
ignoreStrings: true
}],
'@stylistic/js/brace-style': ['error', '1tbs', { allowSingleLine: true }]
}Disallows mixed binary operators.
const noMixedOperators: Rule.RuleModule;
// Rule options
type NoMixedOperatorsOptions = {
groups?: string[][];
allowSamePrecedence?: boolean;
};Usage Examples:
// ✗ Bad - mixed operators without parentheses
const result = a + b * c;
const condition = x && y || z;
// ✓ Good - use parentheses to clarify precedence
const result = a + (b * c);
const condition = (x && y) || z;
// ✓ Good - same operator
const sum = a + b + c;
const product = x * y * z;
// ✓ Good with allowSamePrecedence: true
const mixed = a * b / c; // same precedence operators OKConfiguration:
rules: {
'@stylistic/js/no-mixed-operators': ['error', {
groups: [
['+', '-', '*', '/', '%', '**'],
['&', '|', '^', '~', '<<', '>>', '>>>'],
['==', '!=', '===', '!==', '>', '>=', '<', '<='],
['&&', '||'],
['in', 'instanceof']
],
allowSamePrecedence: true
}]
}Requires parentheses around immediate function invocations.
const wrapIife: Rule.RuleModule;
// Rule options
type WrapIifeOptions =
| 'outside'
| 'inside'
| 'any'
| ['outside' | 'inside' | 'any', {
functionPrototypeMethods?: boolean;
}];Usage Examples:
// ✓ Good with "outside" (default)
(function() {
console.log('IIFE');
})();
// ✓ Good with "inside"
(function() {
console.log('IIFE');
}());
// ✓ Good with "any"
(function() { console.log('IIFE'); })(); // either style OK
(function() { console.log('IIFE'); }());
// ✓ Good with functionPrototypeMethods: true
(function() {}.call(this)); // method calls wrappedConfiguration:
rules: {
'@stylistic/js/wrap-iife': ['error', 'outside', {
functionPrototypeMethods: true
}]
}Requires parenthesis around regex literals.
const wrapRegex: Rule.RuleModule;
// No optionsUsage Examples:
// ✗ Bad - regex without parentheses
const result = /abc/.test(str);
// ✓ Good - regex wrapped in parentheses
const result = (/abc/).test(str);
// Assignment doesn't require wrapping
const pattern = /abc/;
const result = pattern.test(str);Configuration:
rules: {
'@stylistic/js/wrap-regex': 'error'
}interface QualityRules {
'no-extra-parens': Rule.RuleModule;
'no-extra-semi': Rule.RuleModule;
'no-mixed-spaces-and-tabs': Rule.RuleModule;
'no-trailing-spaces': Rule.RuleModule;
'no-multi-spaces': Rule.RuleModule;
'no-whitespace-before-property': Rule.RuleModule;
'max-len': Rule.RuleModule;
'max-statements-per-line': Rule.RuleModule;
'no-floating-decimal': Rule.RuleModule;
'brace-style': Rule.RuleModule;
'no-mixed-operators': Rule.RuleModule;
'wrap-iife': Rule.RuleModule;
'wrap-regex': Rule.RuleModule;
}
interface MaxLenConfig {
code?: number;
tabWidth?: number;
comments?: number;
ignorePattern?: string;
ignoreComments?: boolean;
ignoreTrailingComments?: boolean;
ignoreUrls?: boolean;
ignoreStrings?: boolean;
ignoreTemplateLiterals?: boolean;
ignoreRegExpLiterals?: boolean;
}
interface NoExtraParensConfig {
conditionalAssign?: boolean;
returnAssign?: boolean;
nestedBinaryExpressions?: boolean;
ignoreJSX?: 'none' | 'all' | 'single-line' | 'multi-line';
enforceForArrowConditionals?: boolean;
enforceForSequenceExpressions?: boolean;
enforceForNewInMemberExpressions?: boolean;
enforceForFunctionPrototypeMethods?: boolean;
}Install with Tessl CLI
npx tessl i tessl/npm-stylistic--eslint-plugin-js