# How Surgical Changes Interact with Linting and Formatting Tools

> Learn how Surgical Changes works with linting and formatting tools by scoping them to modified files. Keep intentional edits clear and prevent bulk reformatting.

- Repository: [multica-ai/andrej-karpathy-skills](https://github.com/multica-ai/andrej-karpathy-skills)
- Tags: how-to-guide
- Published: 2026-04-19

---

**Surgical Changes stays compatible with linting and formatting tools when you scope those tools to only the files or lines you actually modified, preventing bulk reformatting from obscuring your intentional edits.**

The *Surgical Changes* principle defined in the `multica-ai/andrej-karpathy-skills` repository guides developers to touch only the code necessary for a specific task. When a project also enforces style through automated tools like ESLint, Prettier, or Black, the default behavior of these tools can clash with this minimalist philosophy.

## The Surgical Changes Principle

According to **CLAUDE.md** §3 (lines 29-41), the *Surgical Changes* guideline instructs contributors to "Touch only what you must. … Don't 'improve' adjacent code, comments, or formatting." This means a pull request should contain only the diff necessary to implement the feature or fix, excluding any opportunistic refactoring of nearby lines.

## Where Linting and Formatting Tools Conflict

Automated linting and formatting tools are designed to enforce consistency across an entire codebase. By default, they often conflict with the *Surgical Changes* rule:

- **Full-file formatting**: Tools like `prettier --write` or `black` rewrite entire documents, introducing whitespace and line-break changes in sections you never touched.
- **Aggressive auto-fixing**: `eslint --fix` might reorder imports or adjust indentation across the whole file, expanding your diff beyond the surgical scope.
- **Pre-commit hooks**: Hooks configured to run on all staged files can inject unintended changes into your commit.

## How to Reconcile Surgical Changes with Automated Tools

You can maintain code style without violating the *Surgical Changes* principle by scoping tool execution to your actual modifications.

### Limit Formatters to Changed Files Only

Instead of running formatters against the entire codebase, target only the files you edited. Use `git diff` to identify changed files and pipe them to your formatter.

```bash

# Format only JavaScript files that differ from HEAD

git diff --name-only HEAD | grep '\.js$' | xargs npx prettier --write

# Lint only changed files, failing on any new warnings

git diff --name-only HEAD | grep '\.js$' | xargs npx eslint --max-warnings=0

```

This approach ensures that formatting changes are limited to files already touched by your functional edit, keeping the diff minimal.

### Configure Pre-Commit Hooks for Surgical Workflows

Pre-commit hooks should verify style without introducing new changes that expand the commit scope. Configure hooks to run in **check-only mode** or to target only staged hunks.

```yaml

# .husky/pre-commit

#!/usr/bin/env sh

# Check staged files without auto-fixing to avoid unintended edits

git diff --cached --name-only | grep '\.js$' | xargs npx eslint --max-warnings=0

```

Alternatively, use the `--staged` flag if your linter supports it, or configure `lint-staged` to run tools only on git-added files.

### Set CI/CD Checks to Verification Mode

Continuous integration should enforce style consistency without blocking surgical changes due to unrelated formatting drift. Configure CI to run linters in **check-only** mode.

```bash

# In your CI pipeline (e.g., GitHub Actions)

- name: Check formatting
  run: npx prettier --check .
  
- name: Check lint rules
  run: npx eslint . --max-warnings=0

```

This ensures that existing formatting debt does not force a developer to reformat entire files unrelated to their change. Developers apply formatting locally to their specific edits before submitting.

### Adjust Editor Auto-Format Settings

IDE features like "Format on Save" can inadvertently violate *Surgical Changes* by restyling entire files. Configure your editor to format only modified lines.

For VS Code, add to your workspace settings:

```json
{
  "editor.formatOnSave": true,
  "editor.formatOnSaveMode": "modifications"
}

```

The `"modifications"` setting restricts formatting to lines changed since the last git commit, preserving the surgical scope.

## Complete Workflow Example

The following workflow demonstrates a surgical change compatible with formatting tools:

```bash

# 1. Make the minimal functional change

vim src/util.js

# 2. Stage only the intended lines

git add -p src/util.js

# 3. Format only the changed file

git diff --name-only --cached | grep '\.js$' | xargs npx prettier --write

# 4. Re-stage any formatting fixes limited to that file

git add src/util.js

# 5. Verify no new lint errors were introduced

git diff --name-only --cached | grep '\.js$' | xargs npx eslint --max-warnings=0

# 6. Commit the surgical change

git commit -m "Fix race condition in fetchData"

```

## Summary

- **Surgical Changes** requires touching only the code necessary for your task, as defined in [`CLAUDE.md`](https://github.com/multica-ai/andrej-karpathy-skills/blob/main/CLAUDE.md) lines 29-41.
- **Linting and formatting tools** can conflict with this principle when they auto-fix entire files rather than scoped changes.
- **Scope your tools** to changed files only using `git diff` pipelines or `--staged` flags to maintain minimal diffs.
- **Configure CI** in check-only mode to prevent blocking surgical changes due to existing formatting debt.
- **Adjust editor settings** to `"modifications"` mode to keep auto-formatting limited to changed lines.

## Frequently Asked Questions

### How do I prevent Prettier from reformatting the entire file when I only changed one line?

Configure your editor to use `"modifications"` mode or run Prettier only on changed files via the command line. In VS Code, set `editor.formatOnSaveMode: "modifications"` in your workspace settings. Alternatively, use `git diff --name-only HEAD | xargs prettier --write` to target only files you have already modified.

### Will following Surgical Changes cause CI lint checks to fail if the codebase has existing formatting issues?

No, if you configure CI to run in check-only mode without auto-fixing. Set your CI pipeline to use commands like `prettier --check .` or `eslint --max-warnings=0` rather than `--write` or `--fix`. This ensures CI only reports violations without forcing you to reformat unrelated files, keeping your surgical changes minimal while still enforcing standards for new code.

### Can I use pre-commit hooks with Surgical Changes, or will they violate the "touch only what you must" rule?

You can use pre-commit hooks safely by configuring them to run in check-only mode or to target only staged changes. Avoid hooks that run `eslint --fix` or `prettier --write` on all files, as these can introduce unintended formatting changes. Instead, use `lint-staged` or a custom script that runs `git diff --cached --name-only | xargs eslint --max-warnings=0` to verify only your surgical changes without rewriting them.

### Does the Surgical Changes guideline prohibit all formatting improvements, even if they make the code cleaner?

Yes, the guideline explicitly prohibits improving adjacent code, comments, or formatting. As stated in [`CLAUDE.md`](https://github.com/multica-ai/andrej-karpathy-skills/blob/main/CLAUDE.md) lines 29-41, you should "Touch only what you must" and avoid "improving" unrelated aspects of the code. Formatting improvements should be submitted as separate, dedicated pull requests rather than bundled with functional surgical changes. This keeps the codebase history clean and makes code reviews significantly easier.