prefer_spacing
Flags SizedBox widgets used as uniform spacers between the children of a Row, Column or Flex, where the built-in spacing argument says the same thing in one place. Requires Flutter 3.27+.
Scattering SizedBox(height: 10) between every child is easy to get wrong — miss one, or type 12 in the middle — and it puts non-semantic widgets in a list that is supposed to describe content.
This rule is in the opinionated preset, so it is on with preset: opinionated and preset: pedantic.
See also: Flex.spacing
Column( children: [ Text('First'), SizedBox(height: 10), Text('Second'), SizedBox(height: 10), Text('Third'), ],)Column( spacing: 10, children: [Text('First'), Text('Second'), Text('Third')],)The separator patterns too
Section titled “The separator patterns too”separatedBy() and an expand() that yields a spacer are the same thing written differently, and are reported the same way:
// Don'tfinal bad = Row( children: items.separatedBy(const SizedBox(width: 8)),);
// Dofinal good = Row( spacing: 8, children: items,);Non-uniform gaps are left alone
Section titled “Non-uniform gaps are left alone”The spacing argument applies one value everywhere, so a list with deliberately different gaps has no single replacement and is not reported:
// Not reported — 4 and 24 are different gapsfinal mixed = Column( children: [ Text('Label'), SizedBox(height: 4), Text('Value'), SizedBox(height: 24), Divider(), ],);Likewise a spacer on the wrong axis — SizedBox(width: 10) inside a Column — is not a gap between children and is ignored. A SizedBox carrying a child, or both a width and a height, is not a pure spacer either.
Raising the threshold
Section titled “Raising the threshold”Below min_children (default 3) a spacer reads fine inline. Three is the smallest list that can hold two widgets with one gap between them; raise it if you would rather only see the long lists:
many_lints: rules: prefer_spacing: min_children: 5rules: prefer_spacing: min_children: 5Known limitations
Section titled “Known limitations”A Row or Column that already passes spacing: is never reported, even if it also holds SizedBox spacers.
Only a children: list literal is examined. Column(children: buildRows()) is opaque and left alone.
This rule and use_gap are opposing conventions — one removes the spacer widget, the other replaces it with a Gap. opinionated picks this one; use_gap is opt-in by name. Enabling both means every spacer gets two contradictory diagnostics.
Options
Section titled “Options”| Option | Type | Default | Description |
|---|---|---|---|
min_children |
int | 3 |
Minimum number of children in the list before spacers are reported |
Turning this rule off
Section titled “Turning this rule off”rules: prefer_spacing: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Related rules
Section titled “Related rules”use_gap— Opposing convention. Use Gap widget instead of SizedBox for spacing in multi-child widgets.avoid_expanded_as_spacer— Use Spacer instead of Expanded with an empty child.always_pass_global_key— Don’t create a GlobalKey inside build.avoid_conditional_hooks— Never call hooks inside conditionals, loops, or ternaries.