Skip to content

Replace Magic Literal

Find a bare literal — a number like 9.80665 or 86400, a string like "ADMIN" — that carries meaning the reader has to guess at, and replace it with a named constant. The name explains what the value is for, and the single definition becomes the one place to change it if it ever must change.

This cures the Magic Number (and its sibling, the magic string). The tell is a literal whose meaning is not obvious from context, especially one that appears in more than one place. When 0.07 shows up in the pricing module and again in the invoice module, two problems lurk: a reader cannot tell that both mean “the sales tax rate,” and the day the rate changes, you must find and edit every copy — and you will miss one.

A shipping-cost calculation peppered with unexplained numbers. After, each literal is a named constant whose name carries the intent.

// Before
function shippingCost(weightKg: number): number {
if (weightKg > 30) {
return weightKg * 2.5 + 15;
}
return weightKg * 2.5;
}
// After
const RATE_PER_KG = 2.5;
const HEAVY_THRESHOLD_KG = 30;
const HEAVY_SURCHARGE = 15;
function shippingCost(weightKg: number): number {
const base = weightKg * RATE_PER_KG;
return weightKg > HEAVY_THRESHOLD_KG ? base + HEAVY_SURCHARGE : base;
}
flowchart LR
  subgraph Before["Before"]
    A["code: weight * 9.80665"]
    B["code: if status == 2"]
  end
  subgraph After["After"]
    C["GRAVITY = 9.80665"]
    D["STATUS_SHIPPED = 2"]
    C --> E["code: weight * GRAVITY"]
    D --> F["code: if status == STATUS_SHIPPED"]
  end
  Before -.->|"Replace Magic Literal"| After
Bare literals become named constants used at each call site
  1. Declare a constant and assign it the literal value. Give it a name that says what the value means, not what it is — HEAVY_THRESHOLD_KG, not THIRTY.
  2. Find one use of the literal. Confirm it truly means the same thing as the constant — two unrelated 2s are not the same magic number.
  3. Replace that use with the constant.
  4. Run your tests.
  5. Repeat for each remaining use that shares the meaning.
  6. When all matching uses are replaced, the literal lives in exactly one place. Changing the value is now a one-line edit.

Replace a literal whenever its meaning is not self-evident, and especially whenever the same meaningful value appears more than once. The named constant doubles as documentation and as a single point of change.

Two cautions. First, do not replace genuinely self-explanatory literals: index + 1 or multiplying by 2 to double a value needs no constant — a name like ONE only adds noise. Second, watch for coincidental equality: if two 100s mean “percent scale” and “max retries,” they must become two different constants, never one shared name, or a future edit to one will silently corrupt the other.

What problem does Replace Magic Literal solve?
What should the constant be named after?
Two literals happen to share the value 100 but mean different things. What should you do?
Which literal is the best candidate to leave un-named?