flutter_semantic_lints

pub.dev

English | 日本語 | 한국어 | Tiếng Việt | 中文 | Português | हिन्दी + English | Bahasa Indonesia | Türkçe | Español | العربية

Not style. Not formatting.

This package detects meaningless Flutter code.


Why this exists

Most lint packages focus on:

  • style
  • naming
  • best practices

But they miss something critical:

Code that works but makes no sense.

This package detects:

  • conflicting parameters
  • useless parameters
  • no-effect widgets

Rules

box_decoration_color_gradient

Bad:

BoxDecoration(
  color: Colors.red,
  gradient: LinearGradient(...),
)

color is ignored.

Good:

BoxDecoration(
  color: Colors.red,
)

Good:

BoxDecoration(
  gradient: LinearGradient(...),
)

Use either color or gradient, not both.

container_color_decoration

Bad:

Container(
  color: Colors.red,
  decoration: BoxDecoration(...),
)

color conflicts with decoration.

Good:

Container(
  color: Colors.red,
)

Good:

Container(
  decoration: BoxDecoration(
    color: Colors.red,
  ),
)

Move the color into decoration when using decoration.

expanded_flex_one

Bad:

Expanded(flex: 1)

Default value is already 1.

Good:

Expanded(
  child: child,
)

Good:

Expanded(
  flex: 2,
  child: child,
)

Omit flex when the value is 1.

visibility_visible_true

Bad:

Visibility(
  visible: true,
  child: child,
)

The child is already visible.

Good:

child

Good:

Visibility(
  visible: isVisible,
  child: child,
)

Use Visibility when visibility is dynamic.

edge_insets_all_zero

Bad:

EdgeInsets.all(0)

EdgeInsets.zero already represents zero insets.

Good:

EdgeInsets.zero

border_radius_circular_zero

Bad:

BorderRadius.circular(0)

BorderRadius.zero already represents no radius.

Good:

BorderRadius.zero

opacity_one

Bad:

Opacity(
  opacity: 1.0,
  child: ...,
)

No visual effect. Adds cost only.

Good:

child

Good:

Opacity(
  opacity: 0.5,
  child: child,
)

Remove Opacity when the value is 1.0.

padding_zero

Bad:

Padding(
  padding: EdgeInsets.zero,
  child: child,
)

No spacing is added.

Good:

child

transform_scale_one

Bad:

Transform.scale(
  scale: 1.0,
  child: child,
)

The child is not scaled.

Good:

child

rotated_box_zero_turns

Bad:

RotatedBox(
  quarterTurns: 0,
  child: child,
)

The child is not rotated.

Good:

child

empty_sized_box

Bad:

SizedBox()

No width, height, or child is provided.

Good:

SizedBox.shrink()

Good:

SizedBox(width: 8)

Use SizedBox.shrink() when an explicit zero-size placeholder is intended.

Installation

dev_dependencies:
  custom_lint:
  flutter_semantic_lints:

Setup

analyzer:
  plugins:
    - custom_lint

Run

dart run custom_lint

Configuration

All rules are enabled by default.

Disable a rule:

analyzer:
  plugins:
    - custom_lint

custom_lint:
  rules:
    - opacity_one: false

Enable only selected rules:

analyzer:
  plugins:
    - custom_lint

custom_lint:
  enable_all_lint_rules: false
  rules:
    - box_decoration_color_gradient
    - container_color_decoration

Philosophy

  • correctness over style
  • semantics over formatting
  • signal over noise

Rule Categories

conflicting_parameter

  • box_decoration_color_gradient
  • container_color_decoration

useless_parameter

  • expanded_flex_one
  • visibility_visible_true
  • edge_insets_all_zero
  • border_radius_circular_zero

no_effect_widget

  • opacity_one
  • padding_zero
  • transform_scale_one
  • rotated_box_zero_turns
  • empty_sized_box

Not Included

These are intentionally not linted yet:

  • Duration.zero
  • Text('')
  • foregroundDecoration combinations
  • InputDecoration combinations

They may be meaningful depending on the API or context. This package skips rules unless they are almost always correct.

Testing

The example project doubles as integration coverage.

cp example/analysis_options.custom_lint.yaml example/analysis_options.yaml
cd example
dart run custom_lint

Positive cases use // expect_lint: comments. Negative and edge cases live in separate example files and should stay quiet.

Non-goals

  • style lint
  • naming rules
  • formatting
  • architecture opinions

Status

MVP

Implemented rules:

  • BoxDecoration conflict
  • Container conflict
  • Expanded(flex: 1)
  • Opacity(1.0)
  • Visibility(visible: true)
  • EdgeInsets.all(0)
  • BorderRadius.circular(0)
  • Padding(padding: EdgeInsets.zero)
  • Transform.scale(scale: 1.0)
  • RotatedBox(quarterTurns: 0)
  • SizedBox()

Contributing

Only submit rules that:

  • are objectively correct
  • have near-zero false positives
  • are explainable in one sentence

License

MIT

Libraries

flutter_semantic_lints
Custom lint rules that detect semantically meaningless Flutter code.