Magic Numbers
Magic Numbers are unexplained literals that hide intent and duplicate values across the code. Replace them with named constants, enums, or configuration so meaning is explicit and changes happen in one place.
A Magic Number is a raw numeric literal embedded directly in code with no explanation of what it represents. if (age > 17) or total * 1.08 or retry(3) all hide meaning: why 17, what is 1.08, and what is special about 3 retries?
Why It Happens
Typing a literal is faster than declaring a constant. The author knows what 1.08 means right now (sales tax) and moves on. The number may also appear in several places, copied as a literal each time because no shared definition exists. Over months the original meaning fades from collective memory.
Why It Hurts
Readers cannot tell intent from the number alone, so the code is harder to understand and review. When the value must change — the tax rate rises, the age threshold shifts — every occurrence must be found and updated by hand, and missing one creates an inconsistency bug. Identical-looking literals may actually mean different things (two unrelated 7s), making safe search-and-replace impossible. The code resists configuration and testing of edge values.
Warning Signs
- Numeric literals in conditionals, calculations, or array sizing.
- The same number appearing in multiple files.
- Thresholds and limits with no name or comment.
- Bug fixes that involve changing a literal in several places.
Better Alternatives
Replace literals with named constants that state intent: LEGAL_ADULT_AGE = 18, SALES_TAX_RATE = 0.08, MAX_RETRIES = 3. Group related fixed sets into enumerated types. Move values that change by environment or over time into configuration rather than source. Well-known mathematical constants (0, 1, identity values) need no extraction; the rule targets business-meaningful or duplicated numbers.
How to Refactor Out of It
Search for literals in logic and ask, for each, "what does this mean and could it change?" Extract meaningful ones into named constants placed near their domain. Deduplicate copies by pointing them at the single constant. For values that vary by environment, lift them into config with a sensible default. Add a lint rule (most linters offer a no-magic-numbers check with allowed exceptions) to keep new literals out. Validate with tests that the named constant flows correctly to every consumer.