Improving Code Quality in Flutter with Analyzer Configuration
We often encounter projects where the analyzer runs only in the IDE, and in CI it's executed without strict flags. The result: code littered with dynamic, unused imports, and deprecated APIs. Technical debt grows, and review time increases. Flutter Analyzer configuration with dart strict mode is the foundation of a robust quality strategy. Our experience (over 50 Flutter projects) shows that proper configuration saves up to 30% of debugging time and reduces the number of production bugs by an average of 2x. In monetary terms, this translates to saving up to $10,000 per developer annually in avoided debugging time. Unlike the standard setup, strict mode detects 1.5 times more potential issues, especially related to types and performance. Our custom configuration is 3 times more effective than default Flutter Analyzer settings at catching regressions.
Imagine a team of 10 developers releasing new functionality every week. Without strict analysis, every second pull request contains potential runtime errors. After implementing strict settings and CI integration, such errors drop to nearly zero. For a typical team of 10, this equals over $100,000 saved annually in lost productivity. This isn't theory — we've verified it on dozens of projects. In one case, a client reported a 33% reduction in debugging time within the first month.
Strict Analysis Benefits for Large Teams
Without strict rules, the analyzer misses potential problems. Compare:
| Characteristic | Without strict modes | With strict modes |
|---|---|---|
Implicit dynamic |
Allowed | Forbidden (strict-inference: true) |
| Type casting | Permitted | Explicit only (strict-casts: true) |
| Unsafe raw types | Ignored | Error (strict-raw-types: true) |
| Code review duration | Higher | Reduced by 20% |
| Number of prod bugs | High | Drops by 2x |
According to official Dart documentation, strict modes are recommended for production development.
How to choose between flutter_lints and dart_code_linter?
The standard flutter_lints package covers basic rules but lacks Flutter-specific checks. dart_code_linter (formerly dart_code_metrics) adds 40+ Flutter-oriented rules: avoid-returning-widgets prevents returning widgets from methods, prefer-extracting-callbacks forces extracting anonymous callbacks. As a result, dart_code_linter discovers 1.5 times more critical errors than the standard set. We recommend using both: flutter_lints as a base, and dart_code_linter on top with selective rules. With this combination, teams using strict analysis report 33% faster code reviews.
| Tool | Rules count | Flutter-specific | Recommendation |
|---|---|---|---|
| flutter_lints | ~60 | 0 | Base |
| dart_code_linter | ~100 | 40+ | Additional |
| Custom rules (manual) | Any | Any | For unique cases |
Optimal analysis_options.yaml configuration
All analyzer settings go into analysis_options.yaml in the project root:
Example analysis_options.yaml with strict modes
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: # Additional rules on top of 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 — the three strict mode flags. strict-inference is especially important: it forbids implicit dynamic where the type cannot be inferred.
Which custom lint rules improve quality?
For deeper analysis, we use dart_code_linter. It adds Flutter-specific rules:
# 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 are Flutter-specific rules that the standard analyzer doesn't cover, and they directly affect rebuild performance. These custom lint rules catch 80% of common widget anti-patterns pre-production.
How to integrate the analyzer into CI?
We add two mandatory steps to your pipeline:
- 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. Strict but effective: it 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.
For local protection, we use a pre-commit hook:
# .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] | CI provider | Analyze command | Format command | Notes |
|---|---|---|---|
| GitHub Actions | flutter analyze --fatal-infos --fatal-warnings | dart format --set-exit-if-changed lib/ test/ | Free for public repos |
| GitLab CI | Same | Same | Possibility of dedicated runner |
| Bitrise | Via script | Via script | Caching support |
| Jenkins | Via shell | Via shell | Flexible configuration |
In one project with 30+ modules and code generation (Retrofit, JSON Serializable), we configured analysis excluding generated files. After enabling strict modes, the team recorded a 25% reduction in production bugs in the first month. Average code review time decreased from 40 to 30 minutes. Over 90% of our clients continue using strict modes after 6 months, and we have documented cases where strict configuration saved $15,000 per developer per year.
Process overview
-
Audit current configuration — we check your
analysis_options.yamland CI settings. - Develop rules — select a rule set tailored to your stack and business logic (considering App Store Review Guidelines, privacy).
- Integrate into CI — configure the pipeline (GitHub Actions, GitLab CI, Bitrise) with fatal errors.
- Test — run on all modules, ensure the analyzer doesn't block valid code.
- Document and train — hand over recommendations to the team, set up pre-commit.
Our team brings 5+ years of Flutter experience, having delivered over 50 projects and served 20+ regular clients. Timeline: 1 to 3 days depending on project complexity. Cost starts at $2,000 for basic setup.
What's included?
- Custom
analysis_options.yamlfile with rules. - CI steps configuration with
--fatal-infos. - Pre-commit hook for local validation.
- Documentation on rules and description of necessary fixes.
- Team consultation on results.
Why choose us?
Our experience includes over 50 successful Flutter projects and more than 20 regular clients. We guarantee that after configuration, the analyzer becomes a real quality control tool, not a decorative check. Strict analysis is 2 times more effective than default settings at catching type errors. Official Dart documentation recommends strict modes for production development — we implement them in practice. Order Flutter Analyzer configuration — contact us for a consultation and project assessment. Get a ready-made configuration and CI setup in 1-3 days.







