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