ESLint plugin providing custom rules for JavaScript Standard Style linting
npx @tessl/cli install tessl/npm-eslint-plugin-standard@5.0.0eslint-plugin-standard provides custom ESLint rules specifically designed for JavaScript Standard Style linting. It offers four specialized rules with flexible spacing options and callback pattern enforcement that extend ESLint's built-in capabilities.
npm install --save-dev eslint-plugin-standard// Direct plugin import (for programmatic use)
const plugin = require("eslint-plugin-standard");
// Access individual rules
const objectCurlyRule = plugin.rules['object-curly-even-spacing'];For use in ESLint configuration:
module.exports = {
plugins: ["standard"],
rules: {
"standard/object-curly-even-spacing": [2, "either"],
"standard/array-bracket-even-spacing": [2, "either"],
"standard/computed-property-even-spacing": [2, "even"],
"standard/no-callback-literal": [2, ["cb", "callback"]]
}
};// Basic ESLint configuration with the plugin
module.exports = {
plugins: ["standard"],
rules: {
// Enable flexible object spacing - allows either 0 or 1 space consistently
"standard/object-curly-even-spacing": [2, "either"],
// Enable flexible array spacing - allows either 0 or 1 space consistently
"standard/array-bracket-even-spacing": [2, "either"],
// Enable consistent computed property spacing - requires even spacing
"standard/computed-property-even-spacing": [2, "even"],
// Enforce callback error-first pattern
"standard/no-callback-literal": [2, ["cb", "callback"]]
}
};The main export provides the complete ESLint plugin structure with rules and default configuration.
/**
* Main plugin export containing ESLint rules and configuration
*/
const plugin = {
rules: {
"array-bracket-even-spacing": Rule,
"computed-property-even-spacing": Rule,
"object-curly-even-spacing": Rule,
"no-callback-literal": Rule
},
rulesConfig: {
"object-curly-even-spacing": 0,
"array-bracket-even-spacing": 0,
"computed-property-even-spacing": 0,
"no-callback-literal": 0
}
};Enforces consistent spacing inside object curly braces with flexible "either" option that allows 0 or 1 space consistently on both sides.
/**
* Rule: object-curly-even-spacing
* Validates spacing in object literals, destructuring, imports, and exports
* Options: "always" | "never" | "either"
* Configuration options: { arraysInObjects?: boolean, objectsInObjects?: boolean }
*/
"standard/object-curly-even-spacing": [
2, // Error level (0=off, 1=warn, 2=error)
"either", // Allow 0 or 1 space consistently
{
arraysInObjects: boolean, // Exception for arrays in objects (default: false)
objectsInObjects: boolean // Exception for objects in objects (default: false)
}
]
// Rule meta structure:
const objectCurlyEvenSpacingRule = {
meta: {
type: "layout",
docs: {
url: "https://github.com/standard/eslint-plugin-standard#rules-explanations"
}
},
create: (context) => { /* implementation */ }
};Validates:
ObjectPattern - Object destructuring: const {a, b} = objImportDeclaration - Named imports: import {foo, bar} from 'module'ExportNamedDeclaration - Named exports: export {foo, bar}ObjectExpression - Object literals: {a: 1, b: 2}Examples of valid code with "either" option:
// Both consistent - valid
const obj1 = {a: 1, b: 2};
const obj2 = { a: 1, b: 2 };
import {foo, bar} from 'module';
import { baz, qux } from 'other';
const {x, y} = obj;
const { z, w } = obj;
// Inconsistent - invalid
const obj3 = {a: 1, b: 2 }; // mixed spacing
import {foo, bar } from 'module'; // mixed spacing
const {a, b } = obj; // mixed spacing in destructuringEnforces consistent spacing inside array brackets with flexible "either" option that allows 0 or 1 space consistently on both sides.
/**
* Rule: array-bracket-even-spacing
* Validates spacing in array literals and destructuring
* Options: "always" | "never" | "either"
* Configuration options: { singleValue?: boolean, objectsInArrays?: boolean, arraysInArrays?: boolean }
*/
"standard/array-bracket-even-spacing": [
2, // Error level (0=off, 1=warn, 2=error)
"either", // Allow 0 or 1 space consistently
{
singleValue: boolean, // Exception for single elements (default: false)
objectsInArrays: boolean, // Exception for objects in arrays (default: false)
arraysInArrays: boolean // Exception for arrays in arrays (default: false)
}
]
// Rule meta structure:
const arrayBracketEvenSpacingRule = {
meta: {
type: "layout",
docs: {
url: "https://github.com/standard/eslint-plugin-standard#rules-explanations"
}
},
create: (context) => { /* implementation */ }
};Validates:
ArrayPattern - Array destructuring: const [a, b] = arrayArrayExpression - Array literals: [1, 2, 3]Examples of valid code with "either" option:
// Both consistent - valid
const arr1 = [1, 2, 3];
const arr2 = [ 1, 2, 3 ];
const [a, b] = [1, 2]; // destructuring
const [ c, d ] = [3, 4]; // destructuring with spaces
// Inconsistent - invalid
const arr3 = [1, 2, 3 ]; // mixed spacing
const [e, f ] = [5, 6]; // mixed spacing in destructuringEnforces consistent spacing inside computed properties with "even" option that requires matching spacing on both sides.
/**
* Rule: computed-property-even-spacing
* Validates spacing in computed property access and object property definitions
* Options: "always" | "never" | "even"
*/
"standard/computed-property-even-spacing": [
2, // Error level (0=off, 1=warn, 2=error)
"even" // Require consistent spacing (0 or 1 space on both sides)
]
// Rule meta structure:
const computedPropertyEvenSpacingRule = {
meta: {
type: "layout",
docs: {
url: "https://github.com/standard/eslint-plugin-standard#rules-explanations"
}
},
create: (context) => { /* implementation */ }
};Validates:
Property - Computed object properties: {[key]: value}MemberExpression - Computed member access: obj[key]Examples of valid code with "even" option:
// Both sides match - valid
obj[key]; // no spaces
obj[ key ]; // spaces on both sides
const computed = {[dynamicKey]: value}; // no spaces
const spaced = { [dynamicKey]: value }; // spaces on both sides
// Sides don't match - invalid
obj[key ]; // space only on right
obj[ key]; // space only on left
const mixed = {[key ]: value}; // inconsistent spacingEnsures callback functions follow the error-first convention by preventing literal values (except null/undefined) in the first parameter position.
/**
* Rule: no-callback-literal
* Enforces error-first callback pattern
* Options: string[] - Array of callback function names to check
*/
"standard/no-callback-literal": [
2, // Error level (0=off, 1=warn, 2=error)
["cb", "callback"] // Callback function names to validate (default: ["callback", "cb"])
]
// Rule meta structure:
const noCallbackLiteralRule = {
meta: {
type: "suggestion",
docs: {
url: "https://github.com/standard/eslint-plugin-standard#rules-explanations"
}
},
create: (context) => { /* implementation */ }
};Validates:
CallExpression - Function calls matching configured callback namesValid error values (first parameter):
null - No error occurredundefined - No error occurredError objects - Actual error instancesExamples of valid code:
// Valid - proper error-first pattern
callback(null, data);
callback(undefined, data);
callback(error, data); // variable
callback(new Error("message"), data);
callback(getError(), data); // function call
callback(err || null, data); // logical expression
// Invalid - literal values in error position
callback("error message", data); // String literal not allowed
callback(42, data); // Number literal not allowed
callback(true, data); // Boolean literal not allowed
callback(false, data); // Boolean literal not allowedAccess individual rules from the plugin object:
/**
* Access individual rules for programmatic use
*/
const plugin = require("eslint-plugin-standard");
// Get specific rule implementations
const objectCurlyRule = plugin.rules["object-curly-even-spacing"];
const arrayBracketRule = plugin.rules["array-bracket-even-spacing"];
const computedPropertyRule = plugin.rules["computed-property-even-spacing"];
const noCallbackLiteralRule = plugin.rules["no-callback-literal"];
// Each rule object has meta and create properties
const ruleMeta = objectCurlyRule.meta;
const ruleFactory = objectCurlyRule.create;Each rule follows the standard ESLint rule pattern:
/**
* Individual Rule Structure - Each rule follows this exact pattern
*/
interface ESLintRule {
meta: {
type: "layout" | "suggestion";
docs: {
url: "https://github.com/standard/eslint-plugin-standard#rules-explanations";
};
};
create: (context: ESLintContext) => {
// Returns object with AST node type handlers
[nodeType: string]: (node: ASTNode) => void;
};
}
/**
* ESLint Context object passed to rule create function
*/
interface ESLintContext {
options: any[]; // Rule configuration options array
getFirstToken: (node: ASTNode, skip?: number) => Token;
getLastToken: (node: ASTNode, skip?: number) => Token;
getTokenBefore: (node: ASTNode) => Token;
getTokenAfter: (node: ASTNode) => Token;
report: (descriptor: {
node: ASTNode;
message: string;
loc?: SourceLocation;
}) => void;
}/**
* Token object representing a syntax token
*/
interface Token {
type: string; // Token type (e.g., "Punctuator", "Identifier")
value: string; // Token value (e.g., "[", "]", "{")
range: [number, number]; // Character positions [start, end]
loc: {
start: { line: number; column: number };
end: { line: number; column: number };
};
}
/**
* AST Node representing a syntax node
*/
interface ASTNode {
type: "ArrayExpression" | "ArrayPattern" | "ObjectExpression" |
"ObjectPattern" | "Property" | "MemberExpression" |
"ImportDeclaration" | "ExportNamedDeclaration" | "CallExpression";
range: [number, number]; // Character positions [start, end]
loc: {
start: { line: number; column: number };
end: { line: number; column: number };
};
// Additional properties specific to node type
}
/**
* Source location object
*/
interface SourceLocation {
start: { line: number; column: number };
end: { line: number; column: number };
}Rules report errors through the ESLint context:
Each rule's create function returns an object with AST node handlers:
/**
* AST Node handlers returned by rule create functions
*/
interface RuleHandlers {
// object-curly-even-spacing handlers
ObjectPattern?: (node: ASTNode) => void;
ImportDeclaration?: (node: ASTNode) => void;
ExportNamedDeclaration?: (node: ASTNode) => void;
ObjectExpression?: (node: ASTNode) => void;
// array-bracket-even-spacing handlers
ArrayPattern?: (node: ASTNode) => void;
ArrayExpression?: (node: ASTNode) => void;
// computed-property-even-spacing handlers
Property?: (node: ASTNode) => void;
MemberExpression?: (node: ASTNode) => void;
// no-callback-literal handlers
CallExpression?: (node: ASTNode) => void;
}rulesConfig values are 0)[severity, ...options]0 (off), 1 (warn), 2 (error)