many_lints 1.2.0 copy "many_lints: ^1.2.0" to clipboard
many_lints: ^1.2.0 copied to clipboard

A comprehensive collection of custom lint rules, quick fixes, and code assists for Flutter and Dart projects.

example/README.md

many_lints Examples #

This directory contains example code demonstrating every lint rule provided by many_lints. Each file in lib/ corresponds to one rule and marks the relevant bad and good cases. Most files trigger their named lint directly; the two path-based rules (match_lib_folder_structure and prefer_correct_test_file_name) use commented path examples because a flat lib/ file cannot violate either rule. Since the broad example preset is enabled, dart analyze example can also show related diagnostics from other rules.

Setup #

Add to your analysis_options.yaml:

plugins:
  many_lints: ^1.2.0

Excluding paths per rule #

many_lints.yaml in this directory demonstrates per-rule exclude:

rules:
  avoid_only_rethrow:
    exclude:
      - lib/excluded/**

lib/excluded/excluded_example.dart contains the same redundant catch clauses as lib/avoid_only_rethrow_example.dart, but reports nothing — that path is excluded for the rule. Delete many_lints.yaml and run dart analyze again to see the two diagnostics come back.

Note that avoid_commented_out_code does still report in that file. Each exclude sits under one rule and affects only that rule — excluding a path from avoid_only_rethrow says nothing about the other rules. To skip a path for several rules, give each of them its own exclude.

Paths are globs, but a plain path works too — lib/generated/foo.dart is a valid pattern, and you can list as many entries as you like:

rules:
  avoid_only_rethrow:
    exclude:
      - lib/legacy/parser.dart      # one specific file
      - lib/generated/**            # a whole directory tree
      - "**/*.g.dart"               # every generated file

The same rules: block can instead live under a top-level many_lints: key in analysis_options.yaml — the two forms are equivalent.

All Rules #

Rule Description Fix
always_pass_global_key Don't create a GlobalKey inside build. —
always_remove_listener Ensure every addListener() has a matching removeListener() in dispose(). Yes
arguments_ordering Keep named arguments in a configured order. —
async_value_nullable_pattern Matching AsyncValue(:final value?) on a nullable value hides a legitimate null result. Yes
avoid_accessing_collections_by_constant_index Avoid accessing a collection by a constant index inside a loop. —
avoid_accessing_other_classes_private_members Make the underscore mean what everyone reads it as. —
avoid_ad_hoc_left_type A pipeline only composes when every step shares one error type. —
avoid_banned_annotations Ban specific annotations, optionally scoped by directory. —
avoid_banned_exports Ban re-exports of specific libraries, optionally scoped by directory. —
avoid_banned_imports Ban imports of specific libraries, optionally scoped by directory. —
avoid_banned_names Ban specific identifiers from being used as declaration names. —
avoid_banned_types Ban specific types from being named, optionally scoped by directory. —
avoid_bare_await_in_do Awaiting a raw Future inside a Do block escapes the block's tracking. —
avoid_bloc_public_methods Prevent public methods, getters, and setters in Bloc classes. —
avoid_border_all Use Border.fromBorderSide instead of Border.all for const support. Yes
avoid_build_context_in_providers Providers outlive widgets, so they should not receive a BuildContext. —
avoid_cascade_after_if_null Detect cascades after if-null operators without parentheses. Yes
avoid_catch_error Use try/catch instead of Future.catchError. —
avoid_collapsible_if Merge nested if statements with &&. Yes
avoid_collection_equality_checks Avoid comparing collections with == or != as it checks reference equality, not contents. —
avoid_collection_methods_with_unrelated_types Avoid calling collection methods with arguments whose types are unrelated to the collection's type parameter. —
avoid_commented_out_code Detect and flag commented-out code. Yes
avoid_complex_conditions Keep boolean conditions within an operand budget. —
avoid_conditional_hooks Never call hooks inside conditionals, loops, or ternaries. —
avoid_constant_conditions Detect comparisons where both sides are constants. —
avoid_constant_switches Detect switch statements on constant expressions. —
avoid_contradictory_expressions Detect logical AND conditions that always evaluate to false. —
avoid_deep_nesting Keep control flow within a nesting budget. —
avoid_deep_widget_nesting Keep a widget tree within a nesting budget. —
avoid_default_tostring Don't interpolate objects that don't override toString. —
avoid_dollar_outside_do_frame Calling a Do block's extraction function from a nested callback unwinds through code that cannot handle it. —
avoid_dst_unsafe_date_arithmetic Calendar day arithmetic on a local DateTime should not go through Duration. Yes
avoid_duplicate_bloc_event_handlers Register each bloc event type exactly once. —
avoid_duplicate_cascades Detect duplicate cascade sections in cascade expressions. Yes
avoid_duplicate_collection_elements Don't repeat the same element in a collection literal. Yes
avoid_duplicate_mixins Flag a mixin applied twice in one with clause. —
avoid_either_of_future A Future nested in Either or Option escapes the error channel. —
avoid_empty_catch Detect catch clauses that silently discard the failure. —
avoid_empty_setstate Don't call setState with an empty callback. —
avoid_empty_spread Remove spreads of empty collection literals. Yes
avoid_equal_expressions Both operands of a binary expression should not be identical. —
avoid_exit_outside_entrypoint Detect exit() outside the program entrypoint, which kills tests. —
avoid_expanded_as_spacer Use Spacer instead of Expanded with an empty child. Yes
avoid_flexible_outside_flex Only use Flexible and Expanded as direct children of Row, Column, or Flex. —
avoid_focused_tests Detect tests focused with solo:, which silences their siblings. —
avoid_future_ignore Do not silently suppress Future errors with an unexplained ignore call. —
avoid_future_of_either Future<Either> throws away the composition TaskEither already gives you. —
avoid_future_of_option Future<Option> throws away the composition TaskOption already gives you. —
avoid_generics_shadowing Avoid generic type parameters that shadow top-level declarations. Yes
avoid_get_or_else_swallowing_failure getOrElse is handed the failure; ignoring it should be a visible decision. —
avoid_high_cyclomatic_complexity Keep a function within a complexity budget. —
avoid_hooks_outside_build Only call hooks from a hook context. —
avoid_incomplete_copy_with Ensure copyWith methods include all constructor parameters. Yes
avoid_inconsistent_digit_separators Group digit separators at a regular interval. Yes
avoid_incorrect_image_opacity Use Image's opacity parameter instead of wrapping in Opacity. Yes
avoid_inherited_widget_in_initstate Don't look up inherited widgets inside initState. —
avoid_inverted_boolean_checks Use the opposite operator instead of negating a comparison. Yes
avoid_late_context Don't read BuildContext in a late field initializer. —
avoid_late_final_reassignment Flag a late final field assigned twice on one path. —
avoid_long_files Keep a file within a line budget. —
avoid_long_functions Keep function bodies within a line budget. —
avoid_long_parameter_list Keep parameter lists within a budget. —
avoid_map_keys_contains Use containsKey() instead of .keys.contains() for better performance. Yes
avoid_missing_completer_stack_trace Pass the stack trace to Completer.completeError. —
avoid_missing_enum_constant_in_map Cover every enum constant in a map keyed by that enum. —
avoid_misused_hooks Don't call hooks inside loops. —
avoid_misused_test_matchers Detect test matchers used with incompatible value types. —
avoid_mounted_in_setstate Detect mounted checks inside setState callbacks. —
avoid_negated_conditions State the positive case first in an if/else. Yes
avoid_nested_conditional_expressions Flag a conditional nested inside another. —
avoid_nested_do_notation A nested Do block short-circuits on its own instead of failing the outer pipeline. —
avoid_nested_futures Don't declare Future<Future<T>>. —
avoid_nested_shorthands Avoid nesting a dot shorthand inside another dot shorthand invocation. —
avoid_non_null_assertion Don't assert away null with the ! operator. —
avoid_not_encodable_in_to_json Don't put values jsonEncode cannot serialize into a toJson map. —
avoid_notifier_constructors Prevent initialization logic in Notifier constructors. Yes
avoid_only_rethrow Detect catch clauses that only rethrow the exception. Yes
avoid_passing_async_when_sync_expected Don't pass an async closure where a void-returning function is expected. —
avoid_passing_bloc_to_bloc Prevent Bloc/Cubit classes from depending on other Bloc/Cubit instances. —
avoid_passing_build_context_to_blocs Prevent passing BuildContext to Bloc or Cubit classes. —
avoid_public_notifier_properties Prevent public fields, getters, and setters on Notifier classes. —
avoid_recursive_widget_calls Don't build a widget from inside its own build method. —
avoid_redundant_async Flag an async function that never awaits. —
avoid_redundant_else Drop the else when the if branch always exits. Yes
avoid_ref_inside_state_dispose Avoid accessing ref inside the dispose method of a ConsumerState. —
avoid_ref_read_inside_build Subscribe in build; do not read once. Yes
avoid_ref_watch_outside_build Subscribe only in build; read once everywhere else. —
avoid_removed_fpdart_api Names removed in fpdart 1.0.0, with the replacement to use. —
avoid_returning_widgets Extract widget helper methods into separate widget classes. —
avoid_self_compare Flag a value compared against itself with compareTo. —
avoid_shadowed_extension_methods An extension member the extended type already has. —
avoid_shrink_wrap_in_lists Avoid using shrinkWrap in ListView for better scroll performance. Yes
avoid_single_child_in_multi_child_widgets Don't use Column, Row, or other multi-child widgets with only one child. —
avoid_single_field_destructuring Avoid destructuring a single field when direct property access is simpler. Yes
avoid_skipped_tests Detect tests, groups and libraries switched off in place. —
avoid_state_constructors Avoid constructors with logic in State classes. Yes
avoid_throw_in_catch_block Detect throw expressions inside catch blocks. Yes
avoid_throw_in_fp_callback A throw inside an fpdart callback escapes the error channel the pipeline is built to carry. —
avoid_todo_comments Detect TODO comments that reference no tracked issue. —
avoid_too_many_methods Keep a class within a method budget. —
avoid_too_many_widgets_per_build Keep one build method within a widget budget. —
avoid_unassigned_stream_subscriptions Ensure stream subscriptions are assigned to a variable for proper cancellation. —
avoid_unmodified_loop_condition A while loop whose condition the body can never change. —
avoid_unnecessary_call Invoke a function directly instead of through .call(). —
avoid_unnecessary_constructor Remove a constructor identical to the default one. —
avoid_unnecessary_consumer_widgets Don't extend ConsumerWidget if you never use WidgetRef. Yes
avoid_unnecessary_continue Remove a continue that ends a loop body. Yes
avoid_unnecessary_enum_prefix Drop an enum name repeated in its own constants. —
avoid_unnecessary_extends Remove an explicit extends Object. —
avoid_unnecessary_gesture_detector Remove GestureDetector widgets that have no event handlers. Yes
avoid_unnecessary_hook_widgets Don't extend HookWidget if you never call any hooks. Yes
avoid_unnecessary_negations Collapse double negations. Yes
avoid_unnecessary_option An Option that is wrapped and immediately unwrapped earns nothing. —
avoid_unnecessary_overrides Detect overrides that only delegate to super. Yes
avoid_unnecessary_return Remove a bare return; that ends a void function. —
avoid_unnecessary_setstate Detect unnecessary setState calls in lifecycle methods. Yes
avoid_unnecessary_stateful_widgets Detect StatefulWidgets that have no mutable state. Yes
avoid_unrelated_type_casts Don't cast or type-test between unrelated types. —
avoid_unremovable_callbacks_in_listeners Don't pass an inline closure to addListener. —
avoid_unrun_task Discarding a lazy fpdart value silently skips the work it describes. —
avoid_unsafe_collection_methods Check for emptiness before using first, last, single or reduce. —
avoid_untyped_safe_cast safeCast without explicit type arguments infers dynamic and always succeeds. —
avoid_unused_after_null_check A variable null-checked but never used in the guarded branch. —
avoid_wildcard_cases_with_enums Keep exhaustiveness checking by listing enum cases explicitly. —
avoid_wrapping_in_padding Avoid wrapping widgets that support padding in a Padding widget. Yes
banned_usage Ban specific members, such as DateTime.now, optionally scoped by directory. —
check_for_equals_in_render_object_setters Compare before marking a RenderObject dirty. —
check_is_not_closed_after_async_gap Check isClosed before emitting state after an await. —
dispose_fields Ensure State fields with disposal methods are cleaned up in dispose(). Yes
dispose_provided_instances Ensure disposable instances in Riverpod providers are cleaned up with ref.onDispose. Yes
double_literal_format Write double literals with exactly one leading zero and no redundant trailing zeros. Yes
emit_new_bloc_state_instances Emit a new state instance instead of the existing state object. —
enum_constants_ordering Keep enum constants in a configured order. —
format_comment Write comments as capitalised, terminated sentences. —
format_test_name Hold test descriptions to a house pattern. —
function_always_returns_null A nullable-returning function whose every path returns null. —
function_always_returns_same_value Flag a function whose every return yields the same constant. —
handle_bloc_event_subclasses Register a handler for every Bloc event subclass. —
initializers_ordering Keep constructor initializers in field order. —
list_all_equatable_fields Ensure all fields are listed in Equatable props. Yes
map_keys_ordering Keep map literal keys in a configured order. —
match_class_name_pattern Match class names against a regular expression. —
match_getter_setter_field_names Make a getter and setter pair use the same field. —
match_lib_folder_structure Keep folders under lib/ in lower_snake_case. —
match_pattern Match code against a project-supplied pattern and offer its replacement. Yes
max_imports Keep a file within an import budget. —
max_statements Keep a function within a statement budget. —
member_ordering Keep class members in a configured order. —
missing_provider_scope Flutter applications using Riverpod must have a ProviderScope at the root of the widget tree. Yes
never_discard_build_context Don't discard a BuildContext parameter with a wildcard. Yes
no_equal_conditions Flag an if/else-if chain that repeats a condition. —
no_equal_switch_case Flag two switch branches with identical bodies. —
no_equal_then_else Both branches of a condition are identical. —
no_magic_number Give a number a name when it carries a policy. —
no_magic_string Name a string once it is repeated. —
notifier_build Classes annotated with @riverpod must define a build method. Yes
parameters_ordering Keep named parameters in a configured order. —
pass_existing_future_to_future_builder Don't create a new Future inline inside FutureBuilder. —
pass_existing_stream_to_stream_builder Don't create a new Stream inline inside StreamBuilder. —
pattern_fields_ordering Keep pattern fields in a configured order. —
prefer_abstract_final_static_class Classes with only static members should be declared as abstract final. Yes
prefer_add_all Replace an add-only loop with addAll. Yes
prefer_align_over_container Use Align instead of Container when only alignment is set. Yes
prefer_and_then andThen says that the previous value is not used. Yes
prefer_any_or_every Use .any() or .every() instead of .where().isEmpty/.isNotEmpty. Yes
prefer_async_callback Use 'AsyncCallback' instead of 'Future<void> Function()'. Yes
prefer_bloc_extensions Use context.read/watch instead of BlocProvider.of or RepositoryProvider.of. Yes
prefer_boolean_prefixes Name booleans as questions. —
prefer_center_over_align Use Center instead of Align when alignment is center. Yes
prefer_chain_either chainEither lifts a synchronous Either step for you. —
prefer_chaining_over_intermediate_run Several .run() calls in one body are a chain that was never joined up. —
prefer_class_destructuring Use Dart 3 class destructuring when accessing multiple properties on the same object. Yes
prefer_compute_over_isolate_run Use 'compute()' instead of 'Isolate.run()' for web platform compatibility. Yes
prefer_conditional_expressions Collapse a two-way if/else into a conditional expression. —
prefer_const_border_radius Use BorderRadius.all(Radius.circular()) for const support. Yes
prefer_constrained_box_over_container Use ConstrainedBox instead of Container when only constraints is set. Yes
prefer_container Replace sequences of nested widgets with a single Container. Yes
prefer_correct_callback_field_name Name callbacks onSomething, the way Flutter does. —
prefer_correct_edge_insets_constructor Use the simplest EdgeInsets constructor for the given values. Yes
prefer_correct_error_name Name exception and error classes with the matching suffix. —
prefer_correct_future_return_type Expose async results as non-nullable Future values. Yes
prefer_correct_handler_name Name event handlers after the event they answer. —
prefer_correct_identifier_length Keep identifier length within bounds. —
prefer_correct_json_casts Cast JSON values to nullable types. —
prefer_correct_setter_parameter_name Use one parameter name in every setter. —
prefer_correct_test_file_name Name test files so the runner actually runs them. —
prefer_correct_type_name Keep type names within a sensible length and correctly capitalised. —
prefer_declaring_const_constructor Declare a const constructor where the class allows one. —
prefer_do_notation Deeply nested flatMap callbacks read flatter as a Do block. —
prefer_early_return Replace a body-wrapping if with an early-return guard. Yes
prefer_enums_by_name Use .byName() instead of .firstWhere() to look up enum values by name. Yes
prefer_equatable_mixin Prefer using EquatableMixin instead of extending Equatable. Yes
prefer_expect_later Use 'expectLater' instead of 'expect' when testing Futures. Yes
prefer_explicit_function_type Prefer explicit function type annotations over the bare 'Function' type. Yes
prefer_explicit_parameter_names Name the parameters of a function type. —
prefer_explicit_type_arguments Pin the type arguments of the APIs where inference surprises. —
prefer_extracting_callbacks Keep long callbacks out of the widget tree. —
prefer_for_loop_in_children Prefer collection-for syntax over functional list building in widget children. Yes
prefer_from_nullable A null check that builds an Option by hand is what Option.fromNullable is for. Yes
prefer_from_predicate A conditional guarding an Option is one Option.fromPredicate call. Yes
prefer_getter_over_method Make a no-argument value read a getter. —
prefer_immediate_return Return an expression directly instead of via a throwaway variable. Yes
prefer_immutable_bloc_state Ensure Bloc and Cubit state classes are annotated with @immutable. Yes
prefer_immutable_state Ensure classes named as state are annotated with @immutable. Yes
prefer_iterable_of Use List.of() / Set.of() instead of .from() for type-safe copies. Yes
prefer_match_file_name Name a file after the first public declaration in it. —
prefer_moving_to_variable Compute a repeated property or invocation chain once into a variable. —
prefer_multi_bloc_provider Use MultiBlocProvider, MultiBlocListener, or MultiRepositoryProvider instead of nesting. Yes
prefer_named_parameters Name parameters once there are more than a couple. —
prefer_overriding_parent_equality Override == and hashCode when the parent class overrides them. Yes
prefer_padding_over_container Use Padding instead of Container when only padding or margin is set. Yes
prefer_prefixed_global_constants Prefix public top-level constants. —
prefer_primary_constructors Prefer a primary constructor (Dart 3.13+) over a class of final fields plus a field-assigning constructor. Yes
prefer_private_named_parameters Prefer private named parameters (Dart 3.12+) over initializer-list boilerplate. Yes
prefer_return_await Detect missing await on returned Futures inside try-catch. Yes
prefer_returning_condition Return the condition instead of true/false branches. —
prefer_returning_shorthands Use dot shorthand constructors in expression function return values. Yes
prefer_safe_collection_access list.first throws where list.head returns None. Yes
prefer_shorthands_with_constructors Use dot shorthand constructors for common Flutter classes. Yes
prefer_shorthands_with_enums Use dot shorthands instead of explicit enum prefixes. Yes
prefer_shorthands_with_static_fields Use dot shorthands instead of explicit class prefixes for static fields. Yes
prefer_simpler_patterns_null_check Suggest simpler null-check patterns in if-case expressions. Yes
prefer_single_declaration_per_file Keep one top-level declaration per file, with per-type budgets. —
prefer_single_setstate Merge multiple setState calls into a single call. Yes
prefer_single_widget_per_file Keep one public widget per file for better organization. —
prefer_sized_box_square Use SizedBox.square when width and height are equal. Yes
prefer_spacing Use the spacing argument on Row/Column instead of SizedBox spacers. —
prefer_string_parse_extensions Option.fromNullable(int.tryParse(s)) is what toIntOption already is. Yes
prefer_switch_expression Suggest converting switch statements to switch expressions. Yes
prefer_switch_with_enums Use a switch instead of an if-else chain over enum constants. —
prefer_task_either_over_try_catch A repository's failures belong in its signature, not in a try/catch. —
prefer_test_matchers Prefer using a Matcher instead of a literal value in expect(). —
prefer_text_rich Use Text.rich instead of RichText for better accessibility. Yes
prefer_theme_mode_getters Prefer ThemeMode.isDark/isLight/isSystem getters (Flutter 3.44+) over == comparisons. Yes
prefer_transform_over_container Use Transform instead of Container when only transform is set. Yes
prefer_type_over_var Prefer an explicit type annotation over 'var'. Yes
prefer_typed_exceptions Detect throws that give callers nothing to catch selectively. —
prefer_typedefs_for_callbacks Name a multi-parameter function type with a typedef. —
prefer_unit_over_void void is not a value, so an fpdart type parameterised with it stops composing. Yes
prefer_use_callback Use 'useCallback' instead of 'useMemoized' for memoizing functions. Yes
prefer_use_prefix Custom hooks should start with the 'use' prefix. Yes
prefer_void_callback Use 'VoidCallback' instead of 'void Function()'. Yes
prefer_widget_private_members A widget's public API is its constructor. —
prefer_wildcard_pattern Use the wildcard pattern '_' instead of 'Object()' for catch-all cases. Yes
proper_super_calls Enforce correct ordering of super lifecycle calls in State classes. Yes
protected_notifier_properties A Notifier's state, ref and future should not be used from outside the notifier. —
provider_parameters Family provider arguments must have stable equality, or the provider is recreated on every rebuild. —
record_fields_ordering Keep record named fields in a configured order. —
require_atomic_async_updates Re-read shared state after an await instead of writing back a stale value. —
require_mirror_test Detect libraries under lib/ with no matching test file. —
use_class_prefix Require a name prefix for classes deriving from a configured type. Yes
use_class_suffix Require a name suffix for classes deriving from a configured type. Yes
use_closest_build_context Use the inner BuildContext from builder callbacks, not the outer one. Yes
use_dedicated_media_query_methods Use MediaQuery.sizeOf(context) instead of MediaQuery.of(context).size. Yes
use_existing_destructuring Add properties to an existing destructuring instead of accessing them directly. Yes
use_existing_variable Use an existing variable instead of repeating its initializer expression. Yes
use_gap Use Gap widget instead of SizedBox for spacing in multi-child widgets. Yes
use_ref_and_state_synchronously Check ref.mounted before using ref or state after an await. Yes
use_ref_read_synchronously Add a mounted guard before calling ref.read after an await. Yes
use_setstate_synchronously Guard setState after an await with a mounted check. —
use_sliver_prefix Name widgets that return slivers with a Sliver prefix. Yes

Detailed Examples #

avoid_single_child_in_multi_child_widgets #

Multi-child widgets like Column, Row, Wrap should not be used with only a single child.

❌ Bad:

Column(
  children: [Text('Only child')],
)

✅ Good:

Text('Only child')

avoid_unnecessary_consumer_widgets #

ConsumerWidget should only be used when the WidgetRef is actually used.

❌ Bad:

class MyWidget extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // ref is never used
    return Text('Hello');
  }
}

✅ Good:

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text('Hello');
  }
}

avoid_unnecessary_hook_widgets #

HookWidget should only be used when hooks are actually called.

❌ Bad:

class MyWidget extends HookWidget {
  @override
  Widget build(BuildContext context) {
    // No hooks called
    return Text('Hello');
  }
}

✅ Good:

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text('Hello');
  }
}

prefer_align_over_container #

Use Align widget instead of Container when only alignment is set.

❌ Bad:

Container(
  alignment: Alignment.topLeft,
  child: Text('Hello'),
)

✅ Good:

Align(
  alignment: Alignment.topLeft,
  child: Text('Hello'),
)

prefer_any_or_every #

Use .any() instead of .where().isNotEmpty and .every() instead of .where().isEmpty.

❌ Bad:

final hasEven = numbers.where((n) => n.isEven).isNotEmpty;
final allPositive = numbers.where((n) => n < 0).isEmpty;

✅ Good:

final hasEven = numbers.any((n) => n.isEven);
final allPositive = numbers.every((n) => n >= 0);

prefer_center_over_align #

Use Center widget instead of Align when alignment is center.

❌ Bad:

Align(
  alignment: Alignment.center,
  child: Text('Hello'),
)

✅ Good:

Center(
  child: Text('Hello'),
)

prefer_padding_over_container #

Use Padding widget instead of Container when only margin is set.

❌ Bad:

Container(
  margin: EdgeInsets.all(16),
  child: Text('Hello'),
)

✅ Good:

Padding(
  padding: EdgeInsets.all(16),
  child: Text('Hello'),
)

The banned family #

avoid_banned_imports, avoid_banned_exports, avoid_banned_types, avoid_banned_names, avoid_banned_annotations and banned_usage all read the same banned: entry shape and report nothing until configured — they enforce your policy, not a built-in one. See many_lints.yaml.

rules:
  avoid_banned_imports:
    banned:
      - deny: ['dart:io']              # exact match
        in: ['lib/domain/**']          # optional glob scope; omit for everywhere
        message: 'Keep the domain layer platform-independent.'
      - deny_pattern: ['package:legacy_.*']   # anchored to the whole value

Each entry takes deny and/or deny_pattern, plus optional in and message. deny matches exactly — banning async does not ban dart:async — so patterns are always opt-in.

❌ Bad:

// in lib/domain/user_repository.dart
import 'dart:io';

✅ Good:

// in lib/domain/user_repository.dart
abstract class ConfigSource {
  Future<String> read();
}

use_class_prefix #

Requires a configured name prefix for classes deriving from a configured type. Reports nothing until configured — see many_lints.yaml.

rules:
  use_class_prefix:
    entries:
      - type: Repository
        prefix: Db

❌ Bad:

class UserRepository implements Repository {}

✅ Good:

class DbUserRepository implements Repository {}

use_class_suffix #

Requires a configured name suffix for classes deriving from a configured type. Matches through extends, implements, with, or an indirect ancestor.

rules:
  use_class_suffix:
    entries:
      - type: Bloc
        package: bloc
        suffix: Bloc

❌ Bad:

class CounterManager extends Bloc<CounterEvent, int> {}

✅ Good:

class CounterBloc extends Bloc<CounterEvent, int> {}

use_dedicated_media_query_methods #

Use dedicated MediaQuery methods to avoid unnecessary rebuilds.

❌ Bad:

final size = MediaQuery.of(context).size;
final padding = MediaQuery.of(context).padding;
final orientation = MediaQuery.of(context).orientation;

✅ Good:

final size = MediaQuery.sizeOf(context);
final padding = MediaQuery.paddingOf(context);
final orientation = MediaQuery.orientationOf(context);

use_gap #

Use Gap widget instead of SizedBox or Padding for spacing in multi-child widgets.

❌ Bad:

Column(
  children: [
    Text('First'),
    SizedBox(height: 16),
    Text('Second'),
  ],
)

✅ Good:

Column(
  children: [
    Text('First'),
    Gap(16),
    Text('Second'),
  ],
)

Suppressing Diagnostics #

To suppress a specific lint, use comments:

// ignore: many_lints/prefer_center_over_align
const example = Align(alignment: Alignment.center);

// ignore_for_file: many_lints/use_class_suffix

The many_lints/ prefix is required. Unlike SDK lints, a plugin diagnostic is only silenced when the rule name is prefixed with the plugin name, so a bare // ignore: prefer_center_over_align has no effect. The prefix is the key used under plugins: in analysis_options.yaml.

Suppressing by type is also possible via // ignore: type=lint (the type= form is required, and it silences every lint on that line, SDK ones included).

More Information #

See the individual example files in lib/ for complete, runnable code samples.

6
likes
160
points
518
downloads

Documentation

Documentation
API reference

Publisher

verified publisherdominikkrajcer.com

Weekly Downloads

A comprehensive collection of custom lint rules, quick fixes, and code assists for Flutter and Dart projects.

Homepage
Repository (GitHub)
View/report issues
Contributing

Topics

#lint #lints #linter #analyzer #code

License

MIT (license)

Dependencies

analysis_server_plugin, analyzer, analyzer_plugin, yaml

More

Packages that depend on many_lints