no_magic_number
This rule flags a numeric literal used without a name to explain it.
Why use this rule
Section titled “Why use this rule”if (retries > 3) states a policy the reader cannot check and the next person cannot find: the same 3 appears in four other files, and changing the policy means finding all five. if (retries > maxRetries) says what the number is for and gives the change one place to happen.
class UploadPolicy { bool shouldGiveUp(int attempts) => attempts > 3;
Duration backoffFor(int attempt) => Duration(milliseconds: attempt * 250);}Name the policy; the Duration argument was never reported, because a measurement is not a policy:
const maxRetries = 3;const backoffStep = 250;
class UploadPolicy { bool shouldGiveUp(int attempts) => attempts > maxRetries;
Duration backoffFor(int attempt) => Duration(milliseconds: attempt * backoffStep);}Exempting your own measurement types
Section titled “Exempting your own measurement types”If your project has its own spacing or geometry types, add them rather than turning the rule off:
many_lints: rules: no_magic_number: additional_ignored_invocations: [Insets, AppSpacing]rules: no_magic_number: additional_ignored_invocations: [Insets, AppSpacing]class Insets { const Insets.all(double value);}
// Not reported under the configuration above.final gutter = Insets.all(17);Allowing a number your domain uses everywhere
Section titled “Allowing a number your domain uses everywhere”allowed: replaces the defaults, so restate them unless you mean to drop them. additional_allowed: adds to them instead:
rules: no_magic_number: additional_allowed: [100, 360]Known limitations
Section titled “Known limitations”These never report, and none of them is configurable away:
-1, 0, 1 and 2. The vocabulary of indexing, counting and halving. Naming them makes code worse:
int firstOrSentinel(List<int> xs) => xs.isEmpty ? -1 : xs.length ~/ 2;A literal that initialises a declaration. It is already named, and this is the shape the rule asks people to move towards. The check sees through arithmetic, so this counts as one named value:
const maximumStoredBytes = 100 * 1024 * 1024;const declarations, enums and annotation arguments, for the same reason.
Measurements. EdgeInsets, Gap, SizedBox, Size, Offset, Duration, BorderRadius, Radius, Rect, Alignment and their siblings take numbers that are a measurement, not a policy. On a real Flutter app these accounted for 416 of 490 reports; spacing8 is a worse name than 8. See ignored_invocations for the full default list.
Tests. A fixture’s numbers are the test data, and naming each one buries the case it describes. Set ignore_tests: false to include them.
Two things this rule deliberately does still report: a const constructor argument — const EdgeInsets.all(17) still hides what 17 means, unless the type is in the ignore list — and seed or demo data. If a file is data, reach for exclude rather than weakening the rule.
This rule is in the pedantic preset: what counts as magic is a house style, and in a Flutter codebase full of layout numbers the honest default is off.
Options
Section titled “Options”many_lints: rules: no_magic_number: allowed: [-1, 0, 1, 2] additional_ignored_invocations: [Insets] ignore_tests: truerules: no_magic_number: allowed: [-1, 0, 1, 2] additional_ignored_invocations: [Insets] ignore_tests: true| Option | Type | Default | Description |
|---|---|---|---|
allowed |
list of numbers | [-1, 0, 1, 2] |
Numbers that never report |
additional_allowed |
list of numbers | [] |
Numbers to add to the defaults, instead of restating them |
ignored_invocations |
list of strings | [BorderRadius, Radius, EdgeInsets, EdgeInsetsDirectional, EdgeInsetsGeometry, Gap, SliverGap, SizedBox, Size, Offset, Duration, Rect, Alignment] |
Constructors and methods whose numeric arguments are a measurement |
additional_ignored_invocations |
list of strings | [] |
Names to add to that list |
ignore_tests |
bool | true |
Skip files under test/ |
Turning this rule off
Section titled “Turning this rule off”To disable this rule:
rules: no_magic_number: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Related rules
Section titled “Related rules”no_magic_string— Name a string once it is repeated.prefer_moving_to_variable— Compute a repeated property or invocation chain once into a variable.avoid_accessing_other_classes_private_members— Make the underscore mean what everyone reads it as.avoid_commented_out_code— Detect and flag commented-out code.