CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-stylistic--eslint-plugin-js

JavaScript stylistic rules for ESLint that enforce code formatting and style consistency without changing code logic.

Pending
Overview
Eval results
Files

code-quality-consistency.mddocs/

Code Quality and Consistency

Rules that prevent common stylistic issues and enforce consistent patterns across codebases.

no-extra-parens

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' }]
}

no-extra-semi

Disallows unnecessary semicolons.

const noExtraSemi: Rule.RuleModule;

// No options

Usage 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'
}

no-mixed-spaces-and-tabs

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'
}

no-trailing-spaces

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 spaces

Configuration:

rules: {
  '@stylistic/js/no-trailing-spaces': ['error', { skipBlankLines: true }]
}

no-multi-spaces

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 OK

Configuration:

rules: {
  '@stylistic/js/no-multi-spaces': ['error', { 
    exceptions: { Property: true },
    ignoreEOLComments: true 
  }]
}

no-whitespace-before-property

Disallows whitespace before properties.

const noWhitespaceBeforeProperty: Rule.RuleModule;

// No options

Usage 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'
}

max-len

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 ignored

Configuration:

rules: {
  '@stylistic/js/max-len': ['error', {
    code: 100,
    tabWidth: 2,
    ignoreUrls: true,
    ignoreStrings: true,
    ignoreTemplateLiterals: true
  }]
}

max-statements-per-line

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 OK

Configuration:

rules: {
  '@stylistic/js/max-statements-per-line': ['error', { max: 1 }]
}

no-floating-decimal

Disallows leading or trailing decimal points in numeric literals.

const noFloatingDecimal: Rule.RuleModule;

// No options

Usage 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'
}

brace-style

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 }]
}

Common Quality Combinations

Strict Quality Rules

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 }]
}

Relaxed Quality Rules

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 }]
}

no-mixed-operators

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 OK

Configuration:

rules: {
  '@stylistic/js/no-mixed-operators': ['error', {
    groups: [
      ['+', '-', '*', '/', '%', '**'],
      ['&', '|', '^', '~', '<<', '>>', '>>>'],
      ['==', '!=', '===', '!==', '>', '>=', '<', '<='],
      ['&&', '||'],
      ['in', 'instanceof']
    ],
    allowSamePrecedence: true
  }]
}

wrap-iife

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 wrapped

Configuration:

rules: {
  '@stylistic/js/wrap-iife': ['error', 'outside', { 
    functionPrototypeMethods: true 
  }]
}

wrap-regex

Requires parenthesis around regex literals.

const wrapRegex: Rule.RuleModule;

// No options

Usage 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'
}

Type Definitions

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

docs

array-formatting.md

code-quality-consistency.md

function-formatting.md

index.md

line-breaks-newlines.md

modern-javascript.md

object-formatting.md

plugin-configuration.md

punctuation-operators.md

spacing-indentation.md

tile.json