flutter_semantic_lints
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
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_gradientcontainer_color_decoration
useless_parameter
expanded_flex_onevisibility_visible_trueedge_insets_all_zeroborder_radius_circular_zero
no_effect_widget
opacity_onepadding_zerotransform_scale_onerotated_box_zero_turns
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)
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.