Skip to content

Code Style

Language-agnostic style rules that apply across all code files.

2-Space Indentation

Use 2 spaces for each level of indentation. Never use tabs. Never use 4 spaces.

javascript
function process(items) {
  for (const item of items) {
    if (item.valid) {
      handle(item);
    }
  }
}

Check for tabs:

sh
node checks/tabs.js file.ext

80-Character Line Limit

Wrap lines at 80 characters. Break at logical points:

DON'T

css
.header { background: linear-gradient(135deg, rgba(255, 255, 255, 0.9) 0%, rgba(240, 240, 240, 0.8) 100%); }

DO

css
.header {
  background: linear-gradient(
    135deg,
    rgba(255, 255, 255, 0.9) 0%,
    rgba(240, 240, 240, 0.8) 100%
  );
}

Check for long lines:

sh
node checks/line-length.js file.ext

Maintain Indentation on Blank Lines

Blank lines inside nested blocks must have the same indentation as surrounding code. Only module-level blank lines (between top-level declarations) may be truly empty.

DON'T — empty line with no spaces inside a block

javascript
export default defineConfig({
··testDir: "./e2e",

··fullyParallel: true,
});

DO — blank line maintains 2-space indentation

javascript
export default defineConfig({
··testDir: "./e2e",
··
··fullyParallel: true,
});

(The · represents a space character.)

Check for violations:

sh
node checks/blank-line-indent.js file.ext

Agent limitation: read_file and replace_string_in_file strip trailing whitespace—they cannot see or edit blank line indentation. Use terminal:

sh
cat file.ext | cat -e | grep -n '^\$'      # find empty lines (should be module-level)
cat file.ext | cat -e | grep -n '^  \$'    # find 2-space lines (should be inside blocks)
sed -i '' '42s/^$/  /' file.ext            # add indentation to line 42
sed -i '' '42s/^  $//' file.ext            # remove indentation from line 42

Consistent Brace Style

Opening braces on the same line as the statement:

javascript
if (condition) {
  // code
} else {
  // code
}

function example() {
  // code
}

Trailing Commas

Use trailing commas in multiline structures:

javascript
const config = {
  name: "example",
  version: "1.0.0",
  enabled: true,
};

Comments Explain Why, Not What

Comments that explain what code does indicate a missing well-named function or variable. Extract the code into a named unit instead of commenting it.

The only acceptable comments explain why a decision was made — context that cannot be expressed in code.

DON'T — comment explains what

javascript
// Check if user is admin
if (user.role === "admin" || user.permissions.includes("all")) {
  // ...
}

DO — extract to named function

javascript
if (hasAdminAccess(user)) {
  // ...
}

DON'T — comment restates the code

javascript
// Increment counter
counter++;

DO — comment explains why

javascript
// Skip the first element — it's always the header row
for (const row of rows.slice(1)) {

Note: Documentation is not comments. Documentation (JSDoc, docstrings, README files) describes the public interface — what a function does, its parameters, and return values. This is appropriate and expected. The rule against "what" comments applies to inline comments.

javascript
/**
 * Calculates the total price including tax.
 * @param {number} subtotal - The pre-tax amount
 * @param {number} taxRate - Tax rate as a decimal (e.g., 0.08)
 * @returns {number} The total with tax applied
 */
function calculateTotal(subtotal, taxRate) {
  return subtotal * (1 + taxRate);
}