JavaScript stylistic rules for ESLint that enforce code formatting and style consistency without changing code logic.
—
Rules specific to modern JavaScript features including arrow functions, template literals, destructuring, and generator functions.
Requires parens in arrow function arguments.
const arrowParens: Rule.RuleModule;
// Rule options
type ArrowParensOptions =
| 'always'
| 'as-needed'
| ['always' | 'as-needed', {
requireForBlockBody?: boolean;
}];Usage Examples:
// ✓ Good with "as-needed" (default)
const single = x => x * 2;
const multiple = (x, y) => x + y;
const none = () => 'hello';
// ✓ Good with "always"
const single = (x) => x * 2;
const multiple = (x, y) => x + y;
const none = () => 'hello';
// ✓ Good with { requireForBlockBody: true }
const expression = x => x * 2; // expression body, parens optional
const block = (x) => { // block body, parens required
return x * 2;
};Configuration:
rules: {
'@stylistic/js/arrow-parens': ['error', 'as-needed', { requireForBlockBody: true }]
}Enforces consistent spacing before and after arrow functions.
const arrowSpacing: Rule.RuleModule;
// Rule options
type ArrowSpacingOptions = {
before?: boolean;
after?: boolean;
};Usage Examples:
// ✓ Good with default settings (before: true, after: true)
const func = (x) => x * 2;
const async = async (x) => await process(x);
// ✓ Good with custom settings
const func = (x)=>x * 2; // before: false, after: false
const spaced = (x) => x * 2; // before: true, after: trueConfiguration:
rules: {
'@stylistic/js/arrow-spacing': ['error', { before: true, after: true }]
}Enforces the location of arrow function bodies.
const implicitArrowLinebreak: Rule.RuleModule;
// Rule options
type ImplicitArrowLinebreakOptions = 'beside' | 'below';Usage Examples:
// ✓ Good with "beside" (default)
const func = (x) => x * 2;
const multiline = (x) => x
+ y
+ z;
// ✓ Good with "below"
const func = (x) =>
x * 2;
const multiline = (x) =>
x
+ y
+ z;Configuration:
rules: {
'@stylistic/js/implicit-arrow-linebreak': ['error', 'beside']
}Requires or disallows spacing around embedded expressions of template strings.
const templateCurlySpacing: Rule.RuleModule;
// Rule options
type TemplateCurlySpacingOptions = 'always' | 'never';Usage Examples:
// ✓ Good with "never" (default)
const message = `Hello ${name}!`;
const multiline = `
Welcome ${user.name}
Your score is ${user.score}
`;
// ✓ Good with "always"
const message = `Hello ${ name }!`;
const multiline = `
Welcome ${ user.name }
Your score is ${ user.score }
`;Configuration:
rules: {
'@stylistic/js/template-curly-spacing': ['error', 'never']
}Requires or disallows spacing between template tags and their literals.
const templateTagSpacing: Rule.RuleModule;
// Rule options
type TemplateTagSpacingOptions = 'always' | 'never';Usage Examples:
// ✓ Good with "never" (default)
const styled = css`
color: red;
font-size: 16px;
`;
const query = gql`
query GetUser($id: ID!) {
user(id: $id) { name }
}
`;
// ✓ Good with "always"
const styled = css `
color: red;
font-size: 16px;
`;Configuration:
rules: {
'@stylistic/js/template-tag-spacing': ['error', 'never']
}Enforces consistent spacing around * operators in generator functions.
const generatorStarSpacing: Rule.RuleModule;
// Rule options
type GeneratorStarSpacingOptions =
| 'before'
| 'after'
| 'both'
| 'neither'
| {
before?: boolean;
after?: boolean;
named?: 'before' | 'after' | 'both' | 'neither' | { before?: boolean; after?: boolean };
anonymous?: 'before' | 'after' | 'both' | 'neither' | { before?: boolean; after?: boolean };
method?: 'before' | 'after' | 'both' | 'neither' | { before?: boolean; after?: boolean };
};Usage Examples:
// ✓ Good with "after" (default)
function* generator() {
yield 1;
yield 2;
}
const gen = function* () {
yield 'hello';
};
// ✓ Good with "before"
function *generator() {
yield 1;
}
// ✓ Good with "both"
function * generator() {
yield 1;
}
// ✓ Good with custom config
function* namedGen() {} // named: 'after'
const anon = function *() {}; // anonymous: 'before'Configuration:
rules: {
'@stylistic/js/generator-star-spacing': ['error', 'after']
}Enforces spacing around the * in yield* expressions.
const yieldStarSpacing: Rule.RuleModule;
// Rule options
type YieldStarSpacingOptions =
| 'before'
| 'after'
| 'both'
| 'neither'
| {
before?: boolean;
after?: boolean;
};Usage Examples:
// ✓ Good with "after" (default)
function* generator() {
yield* otherGenerator();
yield* [1, 2, 3];
}
// ✓ Good with "before"
function* generator() {
yield *otherGenerator();
}
// ✓ Good with "both"
function* generator() {
yield * otherGenerator();
}
// ✓ Good with "neither"
function* generator() {
yield*otherGenerator();
}Configuration:
rules: {
'@stylistic/js/yield-star-spacing': ['error', 'after']
}Enforces spacing between rest and spread operators and their expressions.
const restSpreadSpacing: Rule.RuleModule;
// Rule options
type RestSpreadSpacingOptions = 'always' | 'never';Usage Examples:
// ✓ Good with "never" (default)
function func(...args) {
return [...args, 'extra'];
}
const {name, ...rest} = user;
const newObj = {...obj, updated: true};
// ✓ Good with "always"
function func(... args) {
return [... args, 'extra'];
}
const {name, ... rest} = user;
const newObj = {... obj, updated: true};Configuration:
rules: {
'@stylistic/js/rest-spread-spacing': ['error', 'never']
}Disallows arrow functions where they could be confused with comparisons.
const noConfusingArrow: Rule.RuleModule;
// Rule options
type NoConfusingArrowOptions = {
allowParens?: boolean;
onlyOneSimpleParam?: boolean;
};Usage Examples:
// ✗ Bad - confusing arrow
const isEven = a => a % 2 === 0 ? true : false;
// ✓ Good - clear with parentheses
const isEven = a => (a % 2 === 0 ? true : false);
// ✓ Good - block body
const isEven = a => {
return a % 2 === 0 ? true : false;
};
// ✓ Good with allowParens: true
const func = (a) => a <= 0 ? 'negative' : 'positive';Configuration:
rules: {
'@stylistic/js/no-confusing-arrow': ['error', { allowParens: true }]
}rules: {
'@stylistic/js/arrow-parens': ['error', 'as-needed'],
'@stylistic/js/arrow-spacing': ['error', { before: true, after: true }],
'@stylistic/js/template-curly-spacing': ['error', 'never'],
'@stylistic/js/generator-star-spacing': ['error', 'after'],
'@stylistic/js/rest-spread-spacing': ['error', 'never']
}
// Result:
const func = x => `Hello ${x}!`;
function* gen() { yield* other(); }
const spread = {...obj};rules: {
'@stylistic/js/arrow-parens': ['error', 'always'],
'@stylistic/js/template-curly-spacing': ['error', 'always'],
'@stylistic/js/generator-star-spacing': ['error', 'both'],
'@stylistic/js/rest-spread-spacing': ['error', 'always']
}
// Result:
const func = (x) => `Hello ${ x }!`;
function * gen() { yield * other(); }
const spread = {... obj};interface ModernJavaScriptRules {
'arrow-parens': Rule.RuleModule;
'arrow-spacing': Rule.RuleModule;
'implicit-arrow-linebreak': Rule.RuleModule;
'template-curly-spacing': Rule.RuleModule;
'template-tag-spacing': Rule.RuleModule;
'generator-star-spacing': Rule.RuleModule;
'yield-star-spacing': Rule.RuleModule;
'rest-spread-spacing': Rule.RuleModule;
'no-confusing-arrow': Rule.RuleModule;
}
interface ArrowSpacingConfig {
before?: boolean;
after?: boolean;
}
interface GeneratorStarSpacingConfig {
before?: boolean;
after?: boolean;
named?: GeneratorSpacingOption;
anonymous?: GeneratorSpacingOption;
method?: GeneratorSpacingOption;
}
type GeneratorSpacingOption =
| 'before'
| 'after'
| 'both'
| 'neither'
| { before?: boolean; after?: boolean };Install with Tessl CLI
npx tessl i tessl/npm-stylistic--eslint-plugin-js