Setting Up Flutter Analyzer for Code Quality
Flutter Analyzer is a built-in static analyzer for Dart/Flutter based on dart analyze. Without configuration it already works in IDE, but in CI it's often ignored or run without proper flags. Result: code with dynamic instead of typed variables, unused imports, deprecated API — all accumulates and migrates to production.
analysis_options.yaml
All analyzer settings are in analysis_options.yaml in project root:
include: package:flutter_lints/flutter.yaml
analyzer:
exclude:
- "**/*.g.dart"
- "**/*.freezed.dart"
- "lib/generated/**"
errors:
invalid_annotation_target: ignore # for freezed
language:
strict-casts: true
strict-inference: true
strict-raw-types: true
linter:
rules:
# Include in addition to flutter_lints
- always_use_package_imports
- avoid_dynamic_calls
- avoid_empty_else
- avoid_print
- avoid_relative_lib_imports
- avoid_slow_async_io
- avoid_type_to_string
- cancel_subscriptions
- close_sinks
- comment_references
- invariant_booleans
- literal_only_boolean_expressions
- no_adjacent_strings_in_list
- prefer_const_constructors
- prefer_const_declarations
- prefer_final_fields
- prefer_final_locals
- prefer_void_to_null
- unnecessary_await_in_return
- unnecessary_statements
- use_build_context_synchronously
strict-casts: true, strict-inference: true, strict-raw-types: true — three strict mode flags. strict-inference is especially important: forbids implicit dynamic where type can't be inferred.
Running in CI
- name: Analyze
run: flutter analyze --fatal-infos --fatal-warnings
- name: Check formatting
run: dart format --output=none --set-exit-if-changed lib/ test/
--fatal-infos turns info messages into errors. Harsh, but effective: forces developers not to ignore minor remarks.
dart format --set-exit-if-changed checks formatting without modifying files — if formatting doesn't match dart format, CI fails.
Custom Lint Rules via dart_code_linter
For deeper analysis — dart_code_linter (formerly dart_code_metrics):
# pubspec.yaml
dev_dependencies:
dart_code_linter: ^1.1.0
# analysis_options.yaml
dart_code_linter:
metrics:
cyclomatic-complexity: 20
lines-of-code: 100
number-of-parameters: 4
maximum-nesting-level: 5
metrics-exclude:
- test/**
rules:
- avoid-unnecessary-setstate
- prefer-extracting-callbacks
- avoid-returning-widgets
- check-for-equals-in-render-methods
avoid-returning-widgets and prefer-extracting-callbacks — Flutter-specific rules that standard analyzer doesn't cover, and they directly impact rebuild performance.
Pre-commit Integration
# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: flutter-analyze
name: Flutter Analyze
language: system
entry: flutter analyze
types: [dart]
pass_filenames: false
- id: dart-format
name: Dart Format
language: system
entry: dart format --set-exit-if-changed
types: [dart]
Timeline: 1 day. Cost is calculated individually.







