Flutter Audit
A static analysis CLI for Flutter projects. Scans your codebase and reports findings across 7 categories — performance, memory safety, UI quality, API hygiene, security, architecture, and code quality — in a single command, in under a second.
$ flutter_audit scan .
OVERALL : 53 / 100 ###########......... NEEDS WORK
Quick start
1. Install (one time)
dart pub global activate flutter_audit
This installs flutter_audit as a global Dart CLI, isolated from your
project's pubspec — so it won't fight with flutter_riverpod, analyzer,
or any other dependency in your app.
If
flutter_auditisn't on your PATH after activation, add$HOME/.pub-cache/binto your shell's PATH, or invoke viadart pub global run flutter_audit scan .
2. Run on any Flutter project
cd path/to/your/flutter/project
flutter_audit scan .
You'll get a colored terminal report with category scores, issue counts, and the top 5 issues to fix first.
3. Generate a full HTML report
For a self-contained, shareable dashboard with every issue, category breakdowns, and a "fix first" section:
flutter_audit scan . --output=html --report-file=audit-report.html
Then open audit-report.html in any browser. No JS dependencies, no
external assets — drop it in a CI artifact or email it to a teammate.
All commands
# Pretty terminal report (default)
flutter_audit scan .
# Scan a specific project path
flutter_audit scan /path/to/flutter/app
# Full HTML dashboard
flutter_audit scan . --output=html --report-file=audit-report.html
# Machine-readable JSON (for CI pipelines, dashboards, custom tooling)
flutter_audit scan . --output=json --report-file=audit.json
# Fail the CI build when any error/critical issue is found
flutter_audit scan . --fail-on-error
What it catches
21 built-in rules, organized by category:
| Category | Rules |
|---|---|
| Performance | missing_const, avoid_foreach, prefer_listview_builder |
| Memory | dispose_controllers, cancel_subscriptions, close_sinks |
| Security | hardcoded_secret, insecure_http, unsafe_storage |
| API hygiene | print_in_production, missing_try_catch, hardcoded_url |
| Architecture | huge_build_method, deep_widget_nesting, business_logic_in_widget |
| UI quality | missing_key_in_list, avoid_inline_text_style, hardcoded_size |
| Code quality | empty_catch, todo_comment, long_method |
Each finding has one of four severities: critical · error · warning · info.
How scoring works
Each category starts at 100 and loses points per finding:
| Severity | Penalty |
|---|---|
| info | −1 |
| warning | −2 |
| error | −5 |
| critical | −10 |
category_score = max(0, 100 − Σ penalties) — never goes below zero.
The overall score is a weighted average across categories:
| Category | Weight | Reason |
|---|---|---|
| memory | 1.5 | crashes |
| security | 1.5 | breaches |
| performance | 1.2 | user-visible jank |
| api | 1.2 | user-visible network |
| architecture | 1.0 | baseline maintainability |
| ui | 0.8 | cosmetic |
| quality | 0.8 | cosmetic |
overall = round( Σ(score × weight) / Σ(weights) )
Grade labels: EXCELLENT ≥ 90 · GOOD 80–89 · FAIR 70–79 · NEEDS WORK 50–69 · POOR < 50.
Output formats
| Format | Flag | Best for |
|---|---|---|
| Terminal | (default) | Quick local checks, dev loop |
| HTML | --output=html |
Shareable reports, code reviews, CI |
| JSON | --output=json |
Pipelines, dashboards, custom tooling |
Both --output=html and --output=json accept --report-file=<path> to
control where the file is written (defaults to stdout).
CI / CD integration
# .github/workflows/audit.yml
- run: dart pub global activate flutter_audit
- run: flutter_audit scan . --fail-on-error
- run: flutter_audit scan . --output=html --report-file=audit-report.html
- uses: actions/upload-artifact@v4
with:
name: audit-report
path: audit-report.html
Local development
To hack on flutter_audit itself:
git clone https://github.com/yourname/flutter_audit
cd flutter_audit
dart pub get
dart run bin/flutter_audit.dart scan /path/to/any/flutter/project
The example/ directory ships two sample projects you can scan as a
sanity check:
# Should print OVERALL : 100 / 100 EXCELLENT
dart run bin/flutter_audit.dart scan example/clean_project
# Should print findings in every category
dart run bin/flutter_audit.dart scan example/issues_project
Project structure
lib/
├── core/ Scanner, Parser, Rules Engine, Score Calculator
├── rules/ 21 pluggable audit rules (one per file)
├── models/ Data classes (Issue, Report, Severity, AuditScore)
├── output/ Terminal, JSON, and HTML reporters
└── commands/ CLI subcommands
Adding a new rule
- Create
lib/rules/your_rule.dartextendingAuditRule(seelib/rules/base_rule.dart). - Set
categoryto one of:performance,memory,security,api,architecture,ui,quality. - Set
defaultSeverity(info/warning/error/critical). - Implement
check(ParsedFile file) → List<Issue>. - Register it in
lib/commands/scan_command.dart'sdefaultRules().
No changes to the score calculator, reporters, or CLI needed — they're already wired for all 7 categories and 4 severities.
License
MIT
Libraries
- commands/scan_command
- core/parser
- core/rules_engine
- core/scanner
- core/score_calculator
- flutter_audit
- Public API for
flutter_audit. - models/audit_score
- models/issue
- models/report
- models/severity
- output/html_reporter
- output/json_reporter
- output/terminal_reporter
- rules/avoid_foreach_rule
- rules/avoid_inline_text_style_rule
- rules/base_rule
- rules/business_logic_in_widget_rule
- rules/cancel_subscriptions_rule
- rules/close_sinks_rule
- rules/deep_widget_nesting_rule
- rules/dispose_controllers_rule
- rules/empty_catch_rule
- rules/hardcoded_secret_rule
- rules/hardcoded_size_rule
- rules/hardcoded_url_rule
- rules/huge_build_method_rule
- rules/insecure_http_rule
- rules/long_method_rule
- rules/missing_const_rule
- rules/missing_key_in_list_rule
- rules/missing_try_catch_rule
- rules/prefer_listview_builder_rule
- rules/print_in_production_rule
- rules/todo_comment_rule
- rules/unsafe_storage_rule