Code Formatting
Automated and manual formatting practices that reduce cognitive overhead when reading code.
Overview
Code formatting standardises whitespace, indentation, line length, brace placement, and other syntactic layout. The goal is eliminating stylistic diffs from pull requests so reviews focus on logic. Prettier (JavaScript/TypeScript), RuboCop (Ruby), Black (Python), and gofmt (Go) are opinionated formatters that make formatting non-negotiable by automating it entirely.
Origin
gofmt (Rob Pike, 2013) established the "opinionated formatter" model: one canonical style, enforced by a tool, with no configuration. Prettier (James Long, 2017) brought the same philosophy to the JavaScript ecosystem and became the de-facto standard. Black for Python (2018) followed explicitly citing gofmt as inspiration.
Examples
Prettier configuration for a TypeScript project
// .prettierrc.json
// {
// "semi": true,
// "singleQuote": true,
// "trailingComma": "all",
// "printWidth": 100,
// "tabWidth": 2,
// "arrowParens": "always",
// "endOfLine": "lf"
// }
// Before Prettier:
const fn=(x:number,y:number)=>{
return {result:x+y,sum:x*y}
}
// After Prettier (with above config):
const fn = (x: number, y: number) => {
return { result: x + y, sum: x * y };
};
// package.json scripts
// "format": "prettier --write 'src/**/*.{ts,tsx,json,css}'",
// "format:check": "prettier --check 'src/**/*.{ts,tsx,json,css}'"trailingComma: "all" adds trailing commas to function parameters, which minimises diff size when adding a parameter: only the new line changes, not the previous last line. endOfLine: "lf" prevents CRLF/LF conflicts on Windows.
RuboCop configuration for Rails projects
# .rubocop.yml
# AllCops:
# NewCops: enable
# Exclude:
# - 'db/schema.rb'
# - 'bin/**/*'
# - 'vendor/**/*'
#
# Layout/LineLength:
# Max: 120
# AllowedPatterns:
# - '^s*#' # Allow long comments
#
# Style/FrozenStringLiteralComment:
# Enabled: true
# EnforcedStyle: always
#
# Metrics/MethodLength:
# Max: 15
#
# Style/Documentation:
# Enabled: false
# Run:
# rubocop --parallel # check all files
# rubocop -a # autocorrect safe offenses
# rubocop -A # autocorrect all (including unsafe)
# rubocop app/services/**/*.rb # check specific path
# frozen_string_literal: true
class OrderService
def process(order)
validate!(order)
persist(order)
notify(order)
end
endfrozen_string_literal: true at the top of every Ruby file (enforced by RuboCop) freezes string literals, preventing accidental mutation and enabling string deduplication. MRI Ruby uses this internally; enabling it userland-wide can reduce memory usage in large apps.
Use Cases
- 01Pre-commit hooks via Husky + lint-staged that format only staged files, ensuring no unformatted code reaches the repository
- 02CI pipeline checks that fail the build on formatting violations, used as a gate before code review begins
- 03Editor integration (VS Code Prettier extension with "format on save") that applies formatting in real time during development
- 04Onboarding: new engineers do not need to learn the style guide; the formatter enforces it automatically from day one
When Not to Use
- //Generated code (GraphQL generated types, gRPC stubs, migration files) should be excluded from formatter scope
- //When enforcing formatting on a legacy codebase with thousands of files, introduce gradually via per-directory configuration to avoid massive formatting-only commits that pollute git blame
- //Do not mix formatter and linter responsibilities: Prettier handles layout; ESLint handles code quality. Enabling ESLint formatting rules alongside Prettier causes conflicts
Technical Notes
- Prettier's algorithm is based on Philip Wadler's "A prettier printer" (1998), a functional algorithm that computes optimal line breaks given a target width; it does not parse layout heuristics but computes them from the AST
- lint-staged (v13+) runs formatters and linters on git-staged files only, keeping pre-commit hooks fast even on large codebases; it integrates with Husky (v8+) for hook management
- ESLint and Prettier conflict on formatting rules; eslint-config-prettier disables all ESLint rules that conflict with Prettier. Running them both without this config produces fights over semicolons and quotes
- RuboCop autocorrect generates a .rubocop_todo.yml that disables failing cops for existing violations; engineers progressively enable cops by deleting entries from the todo file