saropa_lints 2.0.0
saropa_lints: ^2.0.0 copied to clipboard
985+ custom lint rules for Flutter and Dart. Static analysis for security, accessibility, and performance. Free and open source. 5 tiers plus optional stylistic rules.
Changelog #
All notable changes to this project will be documented in this file. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Looking for older changes?
See CHANGELOG_ARCHIVE.md for versions 0.1.0 through 1.6.0.
2.0.0 - 2026-01-10 #
Changed #
- Rule aliases: Each rule now tracks numerous aliases and alternate names, making it easier to find rules by different naming conventions (e.g.,
avoid_,prefer_,require_variants)
Fixed #
require_text_editing_controller_dispose: Fixed false positives for controllers passed in from callbacks (e.g., Autocomplete'sfieldViewBuilder). Rule now only flags controllers that are actually instantiated by the class (via inline initialization or ininitState), not those assigned from external sources.require_page_controller_dispose: Same ownership-based detection fix as above.
Added #
Riverpod Rules (8 rules)
avoid_ref_read_inside_build: Warns when ref.read() is used inside build() - use ref.watch() for reactivityavoid_ref_watch_outside_build: Warns when ref.watch() is used outside build() - causes subscription leaksavoid_ref_inside_state_dispose: Warns when ref is accessed in dispose() - ref is unavailable thereuse_ref_read_synchronously: Warns when ref.read() is called after await - cache before async gapuse_ref_and_state_synchronously: Warns when ref/state is used after await - cache before async gapavoid_assigning_notifiers: Warns when assigning to notifier variables - breaks provider contractavoid_notifier_constructors: Warns when Notifier has constructor - use build() for initializationprefer_immutable_provider_arguments: Warns when provider arguments are not final
Bloc State Management Rules (8 rules)
check_is_not_closed_after_async_gap: Warns when emit() is called after await without isClosed checkavoid_duplicate_bloc_event_handlers: Warns when multiple onprefer_immutable_bloc_events: Warns when Bloc event classes have mutable fieldsprefer_immutable_bloc_state: Warns when Bloc state classes have mutable fieldsprefer_sealed_bloc_events: Suggests using sealed keyword for event base classesprefer_sealed_bloc_state: Suggests using sealed keyword for state base classesprefer_bloc_event_suffix: Suggests Bloc event classes end with 'Event' suffixprefer_bloc_state_suffix: Suggests Bloc state classes end with 'State' suffix
Riverpod Widget Rules (2 rules)
avoid_unnecessary_consumer_widgets: Warns when ConsumerWidget doesn't use refavoid_nullable_async_value_pattern: Warns when nullable access patterns used on AsyncValue
Collection & Loop Rules (2 rules)
prefer_correct_for_loop_increment: Warns when for loop uses non-standard increment patternsavoid_unreachable_for_loop: Warns when for loop has impossible bounds
Widget Optimization Rules (4 rules)
prefer_single_setstate: Warns when multiple setState calls in same methodprefer_compute_over_isolate_run: Suggests using compute() instead of Isolate.run()prefer_for_loop_in_children: Warns when List.generate used in widget childrenprefer_container: Warns when nested decoration widgets could be Container
Flame Engine Rules (2 rules)
avoid_creating_vector_in_update: Warns when Vector2/Vector3 created in update() - GC churnavoid_redundant_async_on_load: Warns when async onLoad() has no await
Code Quality Rules (4 rules)
prefer_typedefs_for_callbacks: Suggests using typedefs for callback function typesprefer_redirecting_superclass_constructor: Suggests using super parametersavoid_empty_build_when: Warns when buildWhen always returns trueprefer_use_prefix: Suggests using 'use' prefix for custom hooks
Provider Advanced Rules (5 rules)
prefer_immutable_selector_value: Warns when mutable values used in Selectorprefer_provider_extensions: Warns when long provider access chains useddispose_provided_instances: Warns when Provider.create returns disposable without dispose callbackdispose_getx_fields: Warns when GetxController has Worker fields not disposed in onCloseprefer_nullable_provider_types: Warns when Provider type is non-nullable but create may return null
GetX Build Rules (2 rules)
avoid_getx_rx_inside_build: Warns when .obs is used inside build() - memory leaksavoid_mutable_rx_variables: Warns when Rx variables are reassigned - breaks reactivity
Internationalization Rules (4 rules)
prefer_date_format: Warns when raw DateTime methods (toIso8601String, toString) are used - use DateFormat for locale-aware formattingprefer_intl_name: Warns when Intl.message() lacks name parameter - required for translation extractionprefer_providing_intl_description: Warns when Intl.message() lacks desc parameter - helps translators understand contextprefer_providing_intl_examples: Warns when Intl.message() lacks examples parameter - helps translators with placeholders
Error Handling Rules (1 rule)
avoid_uncaught_future_errors: Warns when Future is used without error handling (catchError, onError, or try-catch)
Type Safety Rules (1 rule)
prefer_explicit_type_arguments: Warns when generic types lack explicit type arguments - prevents accidental dynamic typing
Container Widget Rules (5 rules)
prefer_sized_box_square: Warns when SizedBox(width: X, height: X) uses identical values - use SizedBox.square() insteadprefer_center_over_align: Warns when Align(alignment: Alignment.center) is used - use Center widget insteadprefer_align_over_container: Warns when Container is used only for alignment - use Align widget insteadprefer_padding_over_container: Warns when Container is used only for padding - use Padding widget insteadprefer_constrained_box_over_container: Warns when Container is used only for constraints - use ConstrainedBox insteadprefer_multi_bloc_provider: Warns when nested BlocProviders are used - use MultiBlocProvider insteadavoid_instantiating_in_bloc_value_provider: Warns when BlocProvider.value creates a new bloc - memory leak riskavoid_existing_instances_in_bloc_provider: Warns when BlocProvider(create:) returns existing variable - use .value insteadprefer_correct_bloc_provider: Warns when wrong BlocProvider variant is used for the use caseprefer_multi_provider: Warns when nested Providers are used - use MultiProvider insteadavoid_instantiating_in_value_provider: Warns when Provider.value creates a new instance - lifecycle not manageddispose_providers: Warns when Provider lacks dispose callback - resource cleanupproper_getx_super_calls: Warns when GetxController lifecycle methods don't call superalways_remove_getx_listener: Warns when GetX workers are not assigned for cleanupavoid_hooks_outside_build: Warns when Flutter hooks (use* functions) are called outside build methodsavoid_conditional_hooks: Warns when hooks are called inside conditionals (breaks hook rules)avoid_unnecessary_hook_widgets: Warns when HookWidget doesn't use any hooks - use StatelessWidget insteadextend_equatable: Warns when a class overrides operator == but doesn't use Equatablelist_all_equatable_fields: Warns when Equatable class has fields not included in propsprefer_equatable_mixin: Suggests using EquatableMixin instead of extending Equatableenum_constants_ordering: Warns when enum constants are not in alphabetical ordermissing_test_assertion: Warns when a test body has no assertions (expect, verify, etc.)avoid_async_callback_in_fake_async: Warns when async callback is used inside fakeAsync - defeats fake time controlprefer_symbol_over_key: Suggests using constant Keys instead of string literals in testsincorrect_firebase_event_name: Warns when Firebase Analytics event name doesn't follow conventionsincorrect_firebase_parameter_name: Warns when Firebase Analytics parameter name doesn't follow conventionsprefer_transform_over_container: Warns when Container only has transform - use Transform widgetprefer_action_button_tooltip: Warns when IconButton/FAB lacks tooltip for accessibilityprefer_void_callback: Suggests using VoidCallback typedef instead of void Function()avoid_functions_in_register_singleton: Warns when function is passed to registerSingleton (use registerLazySingleton)
Image & Media Rules (4 rules)
require_image_loading_placeholder: Warns when Image.network lacks loadingBuilder - improves UX during image loadrequire_media_loading_state: Warns when VideoPlayer is used without isInitialized check - prevents blank widget displayrequire_pdf_loading_indicator: Warns when PDF viewer lacks loading state handling - large PDFs need load feedbackprefer_clipboard_feedback: Warns when Clipboard.setData lacks user feedback (SnackBar/Toast) - users need confirmation
Disposal & Cleanup Rules (1 rule)
require_stream_subscription_cancel: Warns when StreamSubscription field is not cancelled in dispose() - memory leak risk
Async Safety Rules (5 rules)
avoid_dialog_context_after_async: Warns when Navigator.pop uses context after await in dialog callback - context may be invalidrequire_websocket_message_validation: Warns when WebSocket message is processed without validation/try-catchrequire_feature_flag_default: Warns when RemoteConfig is accessed without fallback value - graceful degradationprefer_utc_for_storage: Warns when DateTime is stored without .toUtc() - causes timezone inconsistenciesrequire_location_timeout: Warns when Geolocator request lacks timeout parameter - GPS can hang indefinitely
Firebase & Maps Rules (8 rules)
prefer_firestore_batch_write: Warns when multiple sequential Firestore writes should use batch operationavoid_firestore_in_widget_build: Warns when Firestore query is inside build() method - causes unnecessary readsprefer_firebase_remote_config_defaults: Warns when RemoteConfig.getInstance() used without setDefaults()require_fcm_token_refresh_handler: Warns when FCM usage lacks onTokenRefresh listener - tokens expirerequire_background_message_handler: Warns when FCM lacks top-level background handler - required for background messagesavoid_map_markers_in_build: Warns when Map Marker() is created inside build() - causes rebuildsrequire_map_idle_callback: Warns when data fetch is on onCameraMove instead of onCameraIdle - too frequentprefer_marker_clustering: Warns when many individual markers are used without clustering - performance issue
Accessibility Rules (7 rules)
require_image_description: Warns when Image lacks semanticLabel or explicit excludeFromSemanticsavoid_semantics_exclusion: Warns when excludeFromSemantics:true is used - should be justified with commentprefer_merge_semantics: Warns when Icon+Text siblings lack MergeSemantics wrapper - better screen reader UXrequire_focus_indicator: Warns when interactive widgets lack visible focus stylingavoid_flashing_content: Warns when animation flashes more than 3 times per second - seizure riskprefer_adequate_spacing: Warns when touch targets have less than 8dp spacing - accessibility guidelineavoid_motion_without_reduce: Warns when animation lacks MediaQuery.disableAnimations check - accessibility
Navigation & Dialog Rules (6 rules)
require_deep_link_fallback: Warns when deep link handler lacks error/not-found fallbackavoid_deep_link_sensitive_params: Warns when deep link contains password/token params - security riskprefer_typed_route_params: Warns when route parameters are used without type parsingrequire_stepper_validation: Warns when Stepper onStepContinue lacks validation before proceedingrequire_step_count_indicator: Warns when multi-step flow lacks progress indicatorrequire_refresh_indicator_on_lists: Warns when ListView.builder lacks RefreshIndicator wrapper
Animation Rules (5 rules)
prefer_tween_sequence: Warns when multiple chained .forward().then() should use TweenSequencerequire_animation_status_listener: Warns when one-shot animation lacks StatusListener for completionavoid_overlapping_animations: Warns when multiple transitions animate the same property (scale, opacity)avoid_animation_rebuild_waste: Warns when AnimatedBuilder wraps large widget trees (Scaffold, etc.)prefer_physics_simulation: Warns when drag-release uses animateTo instead of SpringSimulation
Platform-Specific Rules (7 rules)
avoid_platform_channel_on_web: Warns when MethodChannel is used without kIsWeb check - not available on webrequire_cors_handling: Warns when HTTP calls in web-specific files lack CORS considerationprefer_deferred_loading_web: Warns when heavy packages lack deferred import on web - improves load timerequire_menu_bar_for_desktop: Warns when desktop app lacks PlatformMenuBar - standard desktop UXavoid_touch_only_gestures: Warns when GestureDetector lacks mouse handlers on desktoprequire_window_close_confirmation: Warns when desktop app's WidgetsBindingObserver lacks didRequestAppExitprefer_native_file_dialogs: Warns when showDialog is used for file picking on desktop - use native dialogs
Testing Rules (4 rules)
require_test_cleanup: Warns when test creates files/data without tearDown cleanupprefer_test_variant: Warns when similar tests with different screen sizes should use variantrequire_accessibility_tests: Warns when widget tests lack meetsGuideline accessibility checksrequire_animation_tests: Warns when animated widget tests use pump() without duration
1.8.2 - 2026-01-10 #
Added #
require_text_editing_controller_dispose: Warns when TextEditingController is not disposed in StatefulWidget - very common source of memory leaks in formsrequire_page_controller_dispose: Warns when PageController is not disposed - prevents memory leaks in PageView widgetsrequire_avatar_alt_text: Warns when CircleAvatar lacks semanticLabel - accessibility requirement for screen readersrequire_badge_semantics: Warns when Badge widget is not wrapped in Semantics - notification badges need accessible labelsrequire_badge_count_limit: Warns when Badge shows count > 99 - UX best practice to show "99+" for large countsavoid_image_rebuild_on_scroll: Warns when Image.network is used in ListView.builder - causes unnecessary rebuilds and network requestsrequire_avatar_fallback: Warns when CircleAvatar with NetworkImage lacks onBackgroundImageError - network failures leave broken avatarsprefer_video_loading_placeholder: Warns when video player widgets (Chewie, BetterPlayer) lack placeholder - improves UX during loadrequire_snackbar_duration: Warns when SnackBar lacks explicit duration - ensures consistent UX timingrequire_dialog_barrier_dismissible: Warns when showDialog lacks explicit barrierDismissible - makes dismiss behavior explicitrequire_dialog_result_handling: Warns when showDialog result is not awaited - prevents missed user confirmationsavoid_snackbar_queue_buildup: Warns when showSnackBar is called without clearing previous - prevents stale message queuesrequire_keyboard_action_type: Warns when TextField/TextFormField lacks textInputAction - improves form navigation UXrequire_keyboard_dismiss_on_scroll: Warns when scroll views lack keyboardDismissBehavior - better form UX on scrollprefer_duration_constants: Warns when Duration can use cleaner units (e.g., seconds: 60 -> minutes: 1)avoid_datetime_now_in_tests: Warns when DateTime.now() is used in test files - causes flaky testsrequire_responsive_breakpoints: Warns when MediaQuery width is compared to magic numbers - promotes named breakpoint constantsprefer_cached_paint_objects: Warns when Paint() is created inside CustomPainter.paint() - recreated every framerequire_custom_painter_shouldrepaint: Warns when shouldRepaint always returns true - causes unnecessary repaintsrequire_currency_formatting_locale: Warns when NumberFormat.currency lacks locale - currency format varies by localerequire_number_formatting_locale: Warns when NumberFormat lacks locale - number format varies by localerequire_graphql_operation_names: Warns when GraphQL query/mutation lacks operation name - harder to debugavoid_badge_without_meaning: Warns when Badge shows count 0 without hiding - empty badges confuse usersprefer_logger_over_print: Warns when print() is used instead of dart:developer log() - better log managementprefer_itemextent_when_known: Warns when ListView.builder lacks itemExtent - improves scroll performancerequire_tab_state_preservation: Warns when TabBarView children may lose state on tab switchavoid_bluetooth_scan_without_timeout: Warns when BLE scan lacks timeout - drains batteryrequire_bluetooth_state_check: Warns when BLE operations start without adapter state checkrequire_ble_disconnect_handling: Warns when BLE connection lacks disconnect state listenerrequire_audio_focus_handling: Warns when audio playback lacks AudioSession configurationrequire_qr_permission_check: Warns when QR scanner is used without camera permission check - critical for app storerequire_qr_scan_feedback: Warns when QR scan callback lacks haptic/visual feedbackavoid_qr_scanner_always_active: Warns when QR scanner lacks lifecycle pause/resume handlingrequire_file_exists_check: Warns when file read operations lack exists() check or try-catchrequire_pdf_error_handling: Warns when PDF loading lacks error handlingrequire_graphql_error_handling: Warns when GraphQL result is used without checking hasExceptionprefer_image_size_constraints: Warns when Image lacks cacheWidth/cacheHeight for memory optimizationrequire_lifecycle_observer: Warns when Timer.periodic is used without WidgetsBindingObserver lifecycle handling
Documentation #
- Migration from solid_lints: Complete rewrite of migration_from_solid_lints.md:
- Corrected rule count: solid_lints has 16 custom rules (not ~50)
- Full rule mapping table: saropa_lints implements 15 of 16 rules (94% coverage)
- Fixed mappings:
avoid_final_with_getter→avoid_unnecessary_getter,avoid_unnecessary_return_variable→prefer_immediate_return - Added
no_magic_numberandavoid_late_keywordmappings that were missing - Documented the one missing rule:
avoid_using_api(configurable API restriction)
- ROADMAP.md: Added
avoid_banned_apito Architecture Rules section (inspired by solid_lints'avoid_using_api) - State management guides: New "Using with" guides for popular libraries:
- using_with_riverpod.md - 8 Riverpod-specific rules with examples
- using_with_bloc.md - 8 Bloc-specific rules with examples
- using_with_provider.md - 4 Provider-specific rules with examples
- using_with_getx.md - 3 GetX-specific rules with examples
- using_with_isar.md - Isar enum corruption prevention
- ROADMAP.md: Added 12 new planned rules based on community research:
- Riverpod: AsyncValue order, navigation patterns, package confusion
- Bloc: BlocSelector usage, state over-engineering, manual dispose
- GetX: Context access patterns, static context testing issues
1.8.1 - 2026-01-10 #
Fixed #
avoid_double_for_money: Fixed remaining false positives:- Switched from substring matching to word-boundary matching - variable names are now split into words (camelCase/snake_case aware) and only exact word matches trigger the rule
- Fixes issues like
audioVolumematchingaudorimageUrlVerticalOffsetPercenttriggering false positives - Removed short currency codes (
usd,eur,gbp,jpy,cad,aud,yen) - still too ambiguous even as complete words (e.g., "cad" for CAD files, "aud" for audio-related)
Changed #
- Refactored rule files for better organization:
- Created
money_rules.dart- movedAvoidDoubleForMoneyRule - Created
media_rules.dart- movedAvoidAutoplayAudioRule - Moved
AvoidSensitiveDataInLogsRuletosecurity_rules.dart - Moved
RequireGetItResetInTestsRuletotest_rules.dart - Moved
RequireWebSocketErrorHandlingRuletoapi_network_rules.dart json_datetime_rules.dartnow only contains JSON and DateTime parsing rules
- Created
Quick Fixes #
avoid_double_for_money: Adds review comment for manual attentionavoid_sensitive_data_in_logs: Comments out the sensitive log statementrequire_getit_reset_in_tests: Adds reminder comment for GetIt resetrequire_websocket_error_handling: Adds onError handler stub
1.8.0 - 2026-01-10 #
Changed #
avoid_double_for_money: BREAKING - Rule is now much stricter to eliminate false positives. Only flags unambiguous money terms:price,money,currency,salary,wage, and currency codes (dollar,euro,yen,usd,eur,gbp,jpy,cad,aud). Generic terms liketotal,amount,balance,cost,fee,tax,discount,payment,revenue,profit,budget,expense,incomeare no longer flagged as they have too many non-monetary uses.
Fixed #
avoid_sensitive_data_in_logs: Fixed false positives for null checks and property access. Now only flags direct value interpolation ($password,${password}), not expressions like${credential != null},${password.length}, or${token?.isEmpty}. Pre-compiled regex patterns for better performance.avoid_hardcoded_encryption_keys: Simplified rule to only detect string literals passed directly toKey.fromUtf8(),Key.fromBase64(), etc. - removes false positives from variable name heuristics
1.7.12 - 2026-01-10 #
Fixed #
require_unique_iv_per_encryption: Improved IV variable name detection to avoid false positives like "activity", "private", "derivative" - now uses proper word boundary detection for camelCase and snake_case patterns
Quick Fixes #
require_unique_iv_per_encryption: Auto-replacesIV.fromUtf8/IV.fromBase64withIV.fromSecureRandom(16)
1.7.11 - 2026-01-10 #
Fixed #
avoid_shrinkwrap_in_scrollview: Rule now properly skips widgets withNeverScrollableScrollPhysics- the recommended fix should no longer trigger the lint- Test fixtures: Updated fixture files with correct
expect_lintannotations and disabled conflicting rules in example analysis_options.yaml
1.7.10 - 2026-01-10 #
Fixed #
- Rule detection for implicit constructors: Fixed
avoid_gradient_in_build,avoid_shrinkwrap_in_scrollview,avoid_nested_scrollables_conflict, andavoid_excessive_bottom_nav_itemsrules not detecting widgets created without explicitnew/constkeywords - AST visitor pattern: Rules now use
GeneralizingAstVisitororaddNamedExpressioncallbacks to properly detect both explicit and implicit constructor calls - Test fixtures: Updated expect_lint positions to match actual lint locations
Changed #
- Rule implementation:
AvoidGradientInBuildRulenow usesGeneralizingAstVisitorwith bothvisitInstanceCreationExpressionandvisitMethodInvocation - Rule implementation:
AvoidShrinkWrapInScrollViewRulenow usesaddNamedExpressionto detectshrinkWrap: truedirectly - Rule implementation:
AvoidNestedScrollablesConflictRulenow uses visitor pattern withRecursiveAstVisitor - Rule implementation:
AvoidExcessiveBottomNavItemsRulenow usesaddNamedExpressionto detect excessive items
1.7.9 - 2026-01-09 #
Added #
- 29 New Rules covering disposal, build method anti-patterns, scroll/list issues, cryptography, and JSON/DateTime handling:
Disposal Rules (2 rules)
require_media_player_dispose- Warns when VideoPlayerController/AudioPlayer is not disposedrequire_tab_controller_dispose- Warns when TabController is not disposed
Build Method Anti-Patterns (8 rules)
avoid_gradient_in_build- Warns when Gradient objects are created inside build()avoid_dialog_in_build- Warns when showDialog is called inside build()avoid_snackbar_in_build- Warns when showSnackBar is called inside build()avoid_analytics_in_build- Warns when analytics calls are made inside build()avoid_json_encode_in_build- Warns when jsonEncode is called inside build()avoid_getit_in_build- Warns when GetIt service locator is used inside build()avoid_canvas_operations_in_build- Warns when Canvas operations are used outside CustomPainteravoid_hardcoded_feature_flags- Warns when if(true)/if(false) patterns are used
Scroll and List Rules (7 rules)
avoid_shrinkwrap_in_scrollview- Warns when shrinkWrap: true is used inside a ScrollViewavoid_nested_scrollables_conflict- Warns when nested scrollables don't have explicit physicsavoid_listview_children_for_large_lists- Suggests ListView.builder for large listsavoid_excessive_bottom_nav_items- Warns when BottomNavigationBar has more than 5 itemsrequire_tab_controller_length_sync- Validates TabController length matches tabs countavoid_refresh_without_await- Ensures RefreshIndicator onRefresh returns Futureavoid_multiple_autofocus- Warns when multiple widgets have autofocus: true
Cryptography Rules (4 rules)
avoid_hardcoded_encryption_keys- Warns when encryption keys are hardcodedprefer_secure_random_for_crypto- Warns when Random() is used for cryptographic purposesavoid_deprecated_crypto_algorithms- Warns when MD5, SHA1, DES are usedrequire_unique_iv_per_encryption- Warns when static or reused IVs are detected
JSON and DateTime Rules (8 rules)
require_json_decode_try_catch- Warns when jsonDecode is used without try-catchavoid_datetime_parse_unvalidated- Warns when DateTime.parse is used without try-catchprefer_try_parse_for_dynamic_data- CRITICAL: Warns when int/double/num.parse is used without try-catchavoid_double_for_money- Warns when double is used for money/currency valuesavoid_sensitive_data_in_logs- Warns when sensitive data appears in log statementsrequire_getit_reset_in_tests- Warns when GetIt is used in tests without resetrequire_websocket_error_handling- Warns when WebSocket listeners lack error handlersavoid_autoplay_audio- Warns when autoPlay: true is set on audio/video players
Changed #
- Docs: Updated rule count from 792+ to 821+
- Impact tuning:
avoid_hardcoded_feature_flagsandavoid_autoplay_audiochanged tolowto match INFO severity - Impact tuning:
avoid_double_for_moneypromoted tocriticalto match ERROR severity (financial bugs)
Quick Fixes #
prefer_secure_random_for_crypto: Auto-replacesRandom()withRandom.secure()avoid_datetime_parse_unvalidated: Auto-replacesDateTime.parsewithDateTime.tryParseprefer_try_parse_for_dynamic_data: Auto-replacesint/double/num.parsewithtryParseavoid_autoplay_audio: Auto-setsautoPlay: falseavoid_hardcoded_feature_flags: Adds TODO comment for feature flag replacement
1.7.8 - 2026-01-09 #
Added #
- 25 New Rules covering network performance, state management, testing, security, and database patterns:
Network Performance (6 rules)
prefer_http_connection_reuse- Warns when HTTP clients are created without connection reuseavoid_redundant_requests- Warns about API calls in build()/initState() without cachingrequire_response_caching- Warns when GET responses aren't cachedprefer_pagination- Warns when APIs return large collections without paginationavoid_over_fetching- Warns when fetching more data than neededrequire_cancel_token- Warns when async requests lack cancellation in StatefulWidgets
State Management (3 rules)
require_riverpod_lint- Warns when Riverpod projects don't include riverpod_lintrequire_multi_provider- Warns about nested Provider widgets instead of MultiProvideravoid_nested_providers- Warns about Provider inside Consumer callbacks
Testing (4 rules)
prefer_fake_over_mock- Warns about excessive mocking vs simpler fakesrequire_edge_case_tests- Warns when tests don't cover edge casesprefer_test_data_builder- Warns about complex test objects without buildersavoid_test_implementation_details- Warns when tests verify internal implementation
Security (6 rules)
require_data_encryption- Warns when sensitive data stored without encryptionprefer_data_masking- Warns when sensitive data displayed without maskingavoid_screenshot_sensitive- Warns about sensitive screens without screenshot protectionrequire_secure_password_field- Warns about password fields without secure keyboard settingsavoid_path_traversal- Warns about file path traversal vulnerabilitiesprefer_html_escape- Warns about user content in WebViews without HTML escaping
Database (6 rules)
require_database_migration- Warns about database schema changes without migration supportrequire_database_index- Warns about queries on non-indexed fieldsprefer_transaction_for_batch- Warns about multiple writes not batched in transactionsrequire_hive_database_close- Warns when database connections not properly closedrequire_type_adapter_registration- Warns about Hive type adapters not registeredprefer_lazy_box_for_large- Warns about large data in regular Hive boxes vs lazy boxes
Changed #
- Docs: Updated rule count from 767+ to 792+
- Impact tuning:
prefer_fake_over_mock,prefer_test_data_builder,require_response_caching,avoid_over_fetchingchanged toopinionated
Quick Fix #
require_secure_password_field: Auto-addsenableSuggestions: falseandautocorrect: false
1.7.7 - 2026-01-09 #
Changed #
- Docs: README now has a Limitations section clarifying Dart-only analysis and dependency_overrides behavior.
1.7.6 - 2026-01-09 #
1.7.5 - 2026-01-09 #
Added #
- Opinionated severity: Added LintImpact.opinionated.
- New rule: prefer_future_void_function_over_async_callback.
- Configuration template: Added example/analysis_options_template.yaml with 767+ rules.
Fixed #
- Empty block warnings in async callback fixture tests.
Changed #
- Docs: Updated counts to reflect 767+ rules.
- Severity: Stylistic rules moved to LintImpact.opinionated.
1.7.4 - 2026-01-08 #
- Updated the banner image to show the project name Saropa Lints.
1.7.3 - 2026-01-08 #
1.7.2 - 2026-01-08 #
Added #
- Impact Classification System: Categorized rules by critical, high, medium, and low.
- Impact Report CLI Tool: dart run saropa_lints:impact_report for prioritized violation reporting.
- 47 New Rules: Covering Riverpod, GetX, Bloc, Accessibility, Security, and Testing.
- 11 New Quick Fixes.
1.7.0 - 2026-01-08 #
Added #
- 50 New Rules: Massive expansion across Riverpod, Build Performance, Testing, Security, and Forms.
- Added support for sealed events in Bloc.
1.6.0 and Earlier #
For details on the initial release and versions 0.1.0 through 1.6.0, please refer to CHANGELOG_ARCHIVE.md.