Skip to main content

DX - Code Style

Enforce a consistent code style across every JavaScript and TypeScript file by combining a @stylistic formatting baseline with focused groups of core ESLint rules for control flow, safety, and conventions.

Why Use This Preset?

  1. Applies the @stylistic recommended baseline so formatting stays uniform without a separate formatter in the pipeline.
  2. Groups rules by theme (arrows, objects, operators, safety, and more) so the intent of each ruleset is visible and easy to inspect.
  3. Targets all script extensions (.js, .ts, .jsx, .tsx, .cjs, .cts, .mjs, .mts) so mixed-module projects share one style.
  4. Catches unsafe patterns like eval, implied-eval calls, and throwing non-Error values so common runtime footguns are flagged early.
  5. Sits at the code-style layer so it composes cleanly above ignores and below your language and runtime presets.

Usage

Import dxCodeStyle from the ESLint presets entry point and spread it into the default-export array of eslint.config.ts, right after dxIgnore in the code-style layer.

eslint.config.ts
ts
import {
  dxCodeStyle,
  dxIgnore,
  langTypescript,
  runtimeNode,
} from '@cbnventures/nova/presets/eslint';

export default [
  ...dxIgnore,
  ...dxCodeStyle,
  ...langTypescript,
  ...runtimeNode,
];

What This Preset Configures

The preset registers the @stylistic plugin and applies its recommended ruleset as a baseline, then layers themed groups of core ESLint and @stylistic rules on top. Every group targets all eight script extensions (.js, .ts, .jsx, .tsx, .cjs, .cts, .mjs, .mts), and every rule reports as an error.

Stylistic baseline

Registers the @stylistic plugin and spreads its recommended ruleset for formatting and spacing across all files.

Arrows

RuleWhat it enforces
@stylistic/arrow-parensRequires parentheses around arrow parameters so if (a => b) isn't mistaken for a comparison.

Braces, commas, semicolons

RuleWhat it enforces
@stylistic/brace-styleEnforces 1tbs brace style with no single-line bodies so opening braces sit on the statement line.
@stylistic/comma-dangleRequires trailing commas in multiline code so adding lines doesn't break diffs.
@stylistic/semiRequires semicolons so automatic semicolon insertion never silently changes parsing.
curlyEnforces curly braces on all control structures so single-line bodies don't grow into bugs.

Cleanup

RuleWhat it enforces
no-array-constructorBans the Array constructor so a single-number argument doesn't create a sparse array.
no-consoleBans raw console output so all logging flows through the Logger toolkit battery.
no-multi-assignDisallows chained assignments so each assignment stays visible and types aren't shared.
no-process-exitDisallows process.exit() so error handling follows structured patterns.
no-restricted-exportsBans exporting default and then so modules don't become thenable or break dynamic import.
no-useless-computed-keyDisallows computed keys for static strings so object keys don't look dynamic when they aren't.
no-useless-concatDisallows concatenating two string literals since they should just be one literal.
no-useless-renameDisallows renaming imports, exports, or destructured values to the same name.
prefer-object-spreadRequires spread syntax over Object.assign() so the new object's shape is visible inline.
radixRequires the radix argument in parseInt() so the base is always explicit.

Control flow

RuleWhat it enforces
guard-for-inRequires a hasOwnProperty check in for-in loops so inherited properties aren't iterated.
no-else-returnDisallows else after a return (including else if) so an indentation level is removed.
no-lone-blocksDisallows standalone blocks so nesting without a control statement doesn't mislead readers.
no-lonely-ifDisallows a lone if inside an else so it reads as a flat else if branch.
no-unreachable-loopDisallows loops that always exit after one iteration so the loop construct isn't misleading.

Conventions

RuleWhat it enforces
default-case-lastRequires the default clause to be the last case in a switch so the fallback is at the bottom.
new-capRequires constructors to start with a capital letter so new calls are visually distinct.
spaced-commentRequires a space after // and /* so comment text is never jammed against the delimiter.
symbol-descriptionRequires a description when creating a Symbol so debug output shows a meaningful label.

Functions and classes

RuleWhat it enforces
array-callback-returnRequires returns in array method callbacks so missing returns don't produce undefined.
default-param-lastRequires default-valued parameters to be last so callers can omit trailing arguments.
grouped-accessor-pairsRequires getter and setter for the same property to be adjacent so the pair stays together.
max-classes-per-fileLimits files to one class so each file has a single responsibility.
no-constructor-returnDisallows returning a value inside constructors so the instance is always returned.
no-extra-bindDisallows .bind() on functions that never use this so bind is reserved for real context.
no-loop-funcDisallows functions in loops that reference loop variables so closure-over-mutation bugs are prevented.
no-newDisallows new for side effects without storing the result.
no-return-assignDisallows assignments inside return statements so the assignment isn't overlooked.
no-useless-catchDisallows catch clauses that just rethrow so try/catch only appears when handling.
no-useless-constructorDisallows constructors that do nothing or just call super() unchanged.
prefer-promise-reject-errorsRequires Promise.reject() to receive an Error so rejections carry a stack trace.
prefer-spreadRequires spread syntax over .apply() so a direct call reads clearly.

Arrays

RuleWhat it enforces
@stylistic/array-bracket-newlineForces line breaks inside brackets once there are two or more elements.
@stylistic/array-element-newlineForces each element onto its own line once there are two or more elements.

Objects

RuleWhat it enforces
@stylistic/object-curly-newlineForces curly-brace line breaks by node type so each property gets its own line in larger literals, patterns, imports, and type bodies.
@stylistic/object-property-newlineForces each property onto its own line once the object literal spans multiple lines.
object-shorthandRequires property shorthand so object literals don't repeat names.

Operators

RuleWhat it enforces
@stylistic/no-mixed-operatorsRequires parentheses when mixing operators of different precedence so evaluation order is explicit.
eqeqeqRequires strict equality (===, !==) so type coercion is never hidden.
no-bitwiseDisallows bitwise operators so a stray & or | is caught instead of && or ||.
no-cond-assignDisallows assignment in conditional expressions so = for === is caught.
no-delete-varDisallows deleting variables since bindings are managed through scope.
no-param-reassignDisallows reassigning parameters (including their properties) so mutations stay visible.
no-plusplusForbids ++ and -- so increments are written as explicit assignments.
no-self-compareDisallows comparing a variable to itself so copy-paste bugs like x === x are caught.
no-sequencesDisallows the comma operator so side effects aren't hidden inside expressions.
no-unsafe-negationPrevents confusing negation so !a in b isn't mistaken for !(a in b).
no-voidDisallows the void operator (except as a statement) so undefined is written directly.
operator-assignmentRequires shorthand operator assignments (+=, -=, *=) so the target is written once.
yodaDisallows Yoda conditions so comparisons read variable-first, literal-second.

Quotes

RuleWhat it enforces
@stylistic/quote-propsEnforces quoting all or none of an object's keys so quoting stays consistent.
@stylistic/quotesRequires single quotes so double quotes stay reserved for HTML/JSX attributes.
prefer-templateRequires template literals over string concatenation when expressions are involved.

Safety

RuleWhat it enforces
no-callerDisallows arguments.caller and arguments.callee so code avoids features removed from strict mode.
no-evalDisallows eval() so arbitrary strings are never executed as code.
no-extend-nativeDisallows extending native built-in prototypes so built-in behavior stays predictable.
no-implied-evalDisallows string arguments to setTimeout/setInterval so hidden eval-like execution is prevented.
no-iteratorDisallows the __iterator__ property so code uses the standard Symbol.iterator protocol.
no-new-funcDisallows the Function constructor so code is not compiled from strings like eval.
no-new-wrappersDisallows primitive wrapper constructors so values stay primitives, not objects.
no-octal-escapeDisallows octal escape sequences so strings use standard Unicode or hex escapes.
no-promise-executor-returnDisallows returning a value inside a Promise executor so a missing resolve/reject isn't hidden.
no-protoDisallows the __proto__ property so prototype access uses the standard methods.
no-throw-literalDisallows throwing anything that isn't an Error so stack traces are always available.

Ternary

RuleWhat it enforces
@stylistic/multiline-ternaryDisallows line breaks in ternaries (JSX exempt) so a split ternary is refactored.
no-nested-ternaryDisallows nested ternaries so readers aren't forced to track precedence.
no-unneeded-ternaryDisallows ternaries that can be simplified, like x ? true : false.

Text characters

RuleWhat it enforces
no-irregular-whitespaceDisallows irregular Unicode whitespace in strings, templates, and JSX text so invisible characters don't cause subtle bugs.

Variables

RuleWhat it enforces
no-label-varDisallows labels that share a name with a variable so identifiers stay unambiguous.
no-labelsDisallows labeled statements so control flow uses functions or early returns.
no-shadowDisallows declarations that shadow an outer-scope variable so each name has one binding.
no-unused-expressionsDisallows expressions that are evaluated but never used so dead code doesn't accumulate.
no-unused-varsDisallows unused variables, ignoring _-prefixed args and rest siblings.
no-varDisallows var so bindings are always block-scoped.
one-varRequires one variable declaration per statement so diffs stay clean.
prefer-constRequires const for variables that are never reassigned so stable bindings are obvious.