skip to content

In software engineering, what is the "Boy Scout Rule" (also called the campsite rule), and what does following it look like in an ordinary day-to-day code change?

level: juniorimportance: must knowfreq 55%

answer

  1. Leave the campground cleaner
  2. Uncle Bob, Clean Code
  3. Cleanup amortized into normal work
  4. Touch-frequency targets the hot files
  5. Separate commit from the behaviour change

basics

~20 s

Always leave code a little better than you found it. Whenever you touch a file, make one small safe improvement — a clearer name, a deleted unused line, an extracted helper — so quality slowly rises instead of decaying.

solid answer

~50 s

The Boy Scout Rule, popularized by Robert C. Martin in *Clean Code*, adapts the scouting maxim "leave the campground cleaner than you found it": every time you open a file to do real work, make a small, safe improvement before you leave. Typical moves are renaming a misleading variable, deleting dead code or a stale comment, extracting a well-named function from a long one, replacing a magic number with a named constant, or adding a missing test for the path you just touched. The point is economics: cleanup is amortized across normal work instead of requiring a separately-funded "quality sprint" that never gets scheduled. The rule is deliberately bounded — improvements should be behaviour-preserving refactorings, verifiable by existing tests, and small enough that a reviewer can still see the actual change. It counteracts entropy: without it, every edit adds a little mess and none removes any.

code

text · 9 lines
text
# One fix, two commits — the reviewer can read each on its own.

commit 1 (refactor, no behaviour change):
  - rename `d` -> `daysSinceLastLogin`
  - extract `isDormant(user)` from the 40-line `process()`
  - delete unused helper `oldFormat()`

commit 2 (the actual fix):
  - isDormant(): use `>= 90` instead of `> 90`   # off-by-one bug

go deeper

for a junior

State the rule and give two concrete cheap examples (rename a confusing variable, delete dead code). Mention you'd keep it small and run the tests.

for a middle

Add the discipline: behaviour-preserving only, separate commits, don't inflate the diff, add a test if the file has none, let a formatter own style so review stays about meaning.

for a senior

Frame it economically — cleanup amortized into funded work, automatically targeting the highest-churn files — and name the boundary conditions and failure modes (merge conflicts, blame damage, scope creep, frozen/hotfix code).

for a principal

Position it on the spectrum from opportunistic tidying to Strangler Fig migration, and talk about making it systemic: automated formatting, ratcheting quality gates on changed lines only, hotspot analysis to direct attention, and review norms that reward small cleanups.

## The rule > **"Always leave the code cleaner than you found it."** The phrase comes from the Boy Scouts of America's campsite guidance ("leave the campground cleaner than you found it") and was applied to software by **Robert C. Martin ("Uncle Bob")** in *Clean Code* (2008). It is also called the **campsite rule**. The operational form: *whenever you open a file for any reason — a bug fix, a feature, even a read-through while debugging — make at least one small improvement to it before you close it.* ## Terms used here - **Refactoring** — changing the internal structure of code **without changing its externally observable behaviour**. Renaming a variable is a refactoring; adding a validation check is not (it changes behaviour). - **Code smell** — a surface symptom that usually indicates a deeper design problem: a 400-line function, a variable named `tmp2`, duplicated blocks, a comment explaining what confusing code does. - **Technical debt** — the accumulated cost of shortcuts and decay; like financial debt, you pay "interest" as extra effort on every future change. - **Entropy / code rot** — the tendency of a codebase to get messier over time simply because many people make many local edits under time pressure. - **Diff / pull request (PR)** — the unit a reviewer sees: the set of lines you changed. Cleanup that inflates the diff makes review harder, which is the rule's main tension. ## Why it exists (the economic argument) Big cleanups need to be *scheduled*, *funded*, and *justified to a stakeholder who sees no user-visible benefit*. In practice they get deferred forever. The Boy Scout Rule sidesteps that by making cleanup a **side effect of work you were already doing and already paid for**. Two reinforcing properties: 1. **The code you touch is the code that matters.** Files change with a power-law distribution: a small fraction of files absorb most edits. Opportunistic cleanup automatically concentrates effort exactly there, because those are the files you keep opening. Untouched files stay ugly, but nobody pays interest on them. 2. **You already have the context.** The cheapest moment to fix a bad name is the moment you have just finished figuring out what it actually means. A week later that understanding is gone. ## What counts as a "clean-up" Cheap, low-risk, high-signal moves — roughly in ascending order of risk: | Move | Risk | Example | |---|---|---| | Delete dead code / commented-out block | very low | remove an unused private helper | | Delete or fix a stale/lying comment | very low | comment says "retries 3x", code retries 5 | | Rename a local variable/parameter | low (tool-assisted) | `d` → `daysSinceLastLogin` | | Replace magic value with named constant | low | `86400` → `SECONDS_PER_DAY` | | Extract a named function from a long one | low–medium | pull the 12-line validation block out | | Add a missing test for the path you touched | low, high value | characterization test around the bug | | Simplify a conditional / remove nesting | medium | early `return` instead of nested `if` | | Rename a public/exported symbol | **high** | ripples to every caller — usually out of scope | The rule is *not* a licence to redesign the module. "A little better" is literal. ## The built-in constraints The rule only works when three conditions hold, and a good answer names them: 1. **Behaviour preservation.** Cleanups must be refactorings, not silent behaviour changes. If you "fix" something while tidying, that is a separate, described change. 2. **A safety net.** Tests (or at minimum a type checker plus automated refactoring tools) must be able to catch you. In a file with no tests, the safest "cleanup" is often *adding a test*, not restructuring. 3. **Reviewability.** The functional change must stay visible. Standard practice: put cleanup in **separate commits** (or a separate PR) from the behavioural change, so a reviewer — and later a bisect or a blame — can separate "what changed" from "what moved". ## The failure modes - **Scope creep**: a two-line fix arrives as a 900-line diff. Reviewers rubber-stamp it, and a real bug hides in the noise. - **Blame/history damage**: mass reformatting destroys the usefulness of line-level history unless your tooling can ignore specific commits. - **Merge conflicts**: gratuitous restructuring of a file that three other people have open costs the team more than the mess did. - **Bikeshedding**: turning every review into a style argument. Style should be enforced by an auto-formatter, not by humans; the rule should be spent on *meaning*, not on brace placement. ## Relationship to neighbouring ideas - **Broken windows theory** (Hunt & Thomas, *The Pragmatic Programmer*): visible neglect invites more neglect; one unrepaired mess signals that mess is acceptable. The Boy Scout Rule is the counter-force — fix the broken window while you're there. - **Opportunistic refactoring** (Martin Fowler): the same idea framed as "refactor when you're near the code anyway", contrasted with scheduled refactoring projects. - **Continuous small improvement vs. big-bang rewrite**: the rule is the smallest granularity on that spectrum; larger interventions (Strangler Fig migrations, branch-by-abstraction) are what you escalate to when opportunistic cleanup provably cannot reach the problem. ## How to answer in an interview State the rule, give two or three *concrete* cheap cleanups, then immediately show judgement by naming the boundary: separate commits, behaviour-preserving only, don't balloon the diff, and skip it in code that is frozen, being deleted, or on a hotfix path.

  • Should the cleanup go in the same pull request as the bug fix?
    Ideally the same PR but in separate commits, so the reviewer can read the behavioural change alone; if the cleanup grows past roughly the size of the fix, split it into its own PR and land it first.
  • What do you do when the file you must touch has no tests at all?
    Make adding a characterization test — a test that pins down the current behaviour, right or wrong — your Boy Scout improvement. Structural cleanup without a safety net is a gamble, and the test is the highest-value thing that file is missing.
  • Doesn't reformatting a file destroy git blame?
    Yes, which is why formatting should be automated and applied repo-wide once, then the bulk-format commit added to an ignore-revs list so blame skips it. Ad-hoc reformatting inside a feature PR is a smell, not Boy Scouting.

Like tidying the kitchen as you cook: you wipe the counter and put away the one pan you used, every time. Nobody has to schedule a deep-clean day, and the kitchen never reaches the state where a deep clean is needed.

saying these in an interview costs you the question

  • Treating the rule as permission to rewrite or redesign a module inside a bug-fix PR
  • Mixing behaviour changes into "just cleanup" commits, so a reviewer can't tell what actually changed
  • Restructuring untested legacy code without first adding a characterization test
  • Ad-hoc reformatting that wrecks line-level history and creates merge conflicts
  • Claiming the rule means "the code must be perfect before you leave" rather than "a little better"
  • Spending the cleanup budget on style nits that an auto-formatter should own

context