Skip to content

Repository files navigation

FlutterGuard

IoT Flutter project static analysis CLI for architecture enforcement, code quality, and CI gating.

English | 中文

FlutterGuard scans Flutter/Dart source code and reports architecture boundary breaches, lifecycle/resource leaks, dependency cycles, and size-related code quality issues. The active path is packages/flutterguard_cli/; the legacy runtime-tracing packages are archived under archive/.

Platforms: macOS, Windows, Linux — pure Dart CLI, no native dependencies.

Docs: Usage Guide | Configuration Strategy | Windows Assessment | Spec | Architecture

What It Is

  • A CLI for static analysis of Flutter/Dart projects
  • A YAML-driven architecture enforcement tool
  • An IoT/smart-home aware rule set for Flutter codebases
  • A CI gate that can fail builds on severity thresholds or score thresholds

What It Is Not

  • Not a runtime observability or APM SDK
  • Not a crash reporter
  • Not a general-purpose Dart linter
  • Not a web dashboard or Flutter widget library
  • Does not require an API key and does not upload APKs

Requirements

  • Dart SDK 3.3.0 or newer
  • melos for workspace bootstrap when running from source
  • Supported OS: macOS, Windows, Linux

Install

Option A: pub.dev install (recommended)

macOS / Linux
dart pub global activate flutterguard_cli
# Verify
flutterguard --version

Ensure $HOME/.pub-cache/bin is on your PATH:

export PATH="$PATH:$HOME/.pub-cache/bin"# add to ~/.zshrc or ~/.bashrc
Windows (PowerShell)
dart pub global activate flutterguard_cli
# Verify
flutterguard --version

If the command is not found, ensure %USERPROFILE%\AppData\Local\Pub\Cache\bin is on your PATH:

$env:Path+=";$env:USERPROFILE\AppData\Local\Pub\Cache\bin"

Option B: GitHub Release binary (no Dart SDK at runtime)

Download the matching binary from the GitHub Releases page, then run it directly:

macOS / Linux
chmod +x flutterguard
./flutterguard --version
./flutterguard scan .
Windows (PowerShell)
.\flutterguard.exe--version
.\flutterguard.exe scan .

Option C: source checkout for development

Use the local launcher when you want to run the current checkout without installing or replacing the global flutterguard command.

macOS / Linux
git clone https://github.com/lizy-coding/flutterguard.git
cd flutterguard
dart pub get
./scripts/flutterguard-dev --version
./scripts/flutterguard-dev scan .
Windows (PowerShell)
git clone https://github.com/lizy-coding/flutterguard.git
cd flutterguard
dart pub get
.\scripts\flutterguard-dev.ps1 --version
.\scripts\flutterguard-dev.ps1 scan .

Quick Start

# Scan the current directory
flutterguard scan
# Create and validate a starter config
flutterguard init --profile migration
flutterguard config doctor
flutterguard doctor install
# Inspect the merged effective config
flutterguard config print
# Scan a specific project
flutterguard scan ./my_flutter_app # macOS / Linux
flutterguard scan .\my_flutter_app # Windows# Scan with explicit path flag
flutterguard scan -p /path/to/project # macOS / Linux
flutterguard scan -p D:\path\to\project # Windows# JSON output with CI gate
flutterguard scan . --format json --fail-on high
# Baseline existing issues before enabling a hard CI gate
flutterguard baseline create .
flutterguard baseline stats
flutterguard baseline check . --baseline .flutterguard/baseline.json --no-growth
flutterguard scan . --baseline .flutterguard/baseline.json --fail-on high
# GitHub Code Scanning output
flutterguard scan . --format sarif --baseline .flutterguard/baseline.json
# Export one finding for false-positive feedback
flutterguard issue export --rule mqtt_connection --file lib/device/mqtt.dart --line 42
# Show help
flutterguard --help
flutterguard scan --help

Demo target

flutterguard scan examples/scan_demo

CLI Reference

Commands:

CommandDescription
flutterguard scan [<path>]Scan a project (path defaults to current directory)
flutterguard baseline create [<path>]Create a baseline JSON file for existing issues
flutterguard baseline statsShow baseline fingerprint counts
flutterguard baseline prune [<path>]Remove fixed issues from a baseline
flutterguard baseline check [<path>] --no-growthFail when current issues are missing from baseline
flutterguard doctor installDiagnose executable version and PATH conflicts
flutterguard initCreate a starter flutterguard.yaml
flutterguard init --profile migrationCreate a starter config from a profile
flutterguard init --with-architectureCreate config with architecture layer/module templates
flutterguard config printPrint the merged effective configuration
flutterguard config doctorValidate config, globs, and architecture references
flutterguard issue exportExport one issue as a local feedback JSON bundle
flutterguard rulesList available rules
flutterguard explain <rule-id>Explain one rule
flutterguard --help / -hShow usage
flutterguard --version / -VShow version

Scan options

FlagShortDefaultDescription
<path>.Positional project path (optional, before options)
--path-p.Project path to scan (overridden by positional <path>)
--config-cflutterguard.yamlConfig file path
--format-ftableOutput format: table, json, or sarif
--output-o.flutterguardOutput directory for reports
--verbose-voffShow detailed output with code context
--no-coloroffDisable ANSI terminal colors
--changed-onlyoffOnly scan Dart files changed since --base
--basemainGit base ref for --changed-only
--baselineunsetBaseline JSON file used to hide existing issues
--fail-onnoneCI gate: none / high / medium / low
--min-scoreunsetMinimum score threshold 0–100
--help-hShow scan usage

Exit codes

CodeMeaning
0Success, including help/version and a changed-only scan with no relevant changes
1CI gate failed (issues at/above --fail-on level, or score below --min-score)
2Scan setup error (bad path, missing explicit config, invalid config, or no configured Dart files)

Path resolution

FlutterGuard auto-discovers the project root by walking up from the current directory, looking for flutterguard.yaml, pubspec.yaml, or a lib/ directory. If none are found, it falls back to the current directory.

The --config path is resolved against the target project:

  1. Absolute paths are used as-is and must exist.
  2. Relative paths are resolved from the target project root, never from CWD.
  3. An omitted default flutterguard.yaml uses built-in defaults; any explicitly selected config must exist.

Configuration

Create flutterguard.yaml in your project root.

Recommended strategy:

  1. Start with zero config: flutterguard scan.
  2. Run flutterguard init when you need custom thresholds or excludes.
  3. Use flutterguard config print to inspect merged defaults.
  4. Use flutterguard config doctor before enabling CI gates.
  5. Add architecture layers/modules only after project boundaries are agreed.

For the full decision model, see Configuration Strategy.

Basic config (for most users)

include:
- lib/**exclude:
- lib/generated/**
- lib/**.g.dart
- lib/**.freezed.dart
- lib/**.mocks.dartrules:
large_file:
enabled: truemaxLines: 500large_class:
enabled: truemaxLines: 300large_build_method:
enabled: truemaxLines: 80lifecycle_resource:
enabled: truemissing_const_constructor:
enabled: truedevice_lifecycle:
enabled: truemqtt_connection:
enabled: trueble_scanning:
enabled: truemaxScanDurationMs: 10000iot_security:
enabled: truerequireTls: truepubspec_security:
enabled: true

Full config (with architecture enforcement)

# ... include/exclude/rules from basic config above ...architecture:
layers:
- name: presentationpath: lib/presentation/**allowed_deps: [domain, core]
- name: domainpath: lib/domain/**allowed_deps: [core]
- name: datapath: lib/data/**allowed_deps: [domain, core]
- name: corepath: lib/core/**allowed_deps: []modules:
- name: device_mqttpath: lib/device/mqtt/**allowed_deps: [domain, core]
- name: device_blepath: lib/device/ble/**allowed_deps: [domain, core]detect_cycles: truelayer_violation:
enabled: truemodule_violation:
enabled: true

Important: Architecture rules (layer_violation, module_violation, circular_dependency) require explicit architecture.layers, architecture.modules, and/or architecture.detect_cycles declarations in your config. They do not auto-discover project boundaries.

Glob patterns: Always use forward slashes (/) in YAML config, even on Windows. Do not use backslashes.


Rules

Rule IDLevelDomainPriorityWhat it checksConfig required
large_fileLOWstandardsP2File line count over maxLines
large_classLOWstandardsP2Class body line count over maxLines
large_build_methodMEDIUMperformanceP1build() method line count over maxLines
lifecycle_resource_not_disposedMEDIUMperformanceP1Undisposed StreamSubscription, Timer, AnimationController, TextEditingController, ScrollController, FocusNode, MqttClient, BluetoothDevice, StreamController
missing_const_constructorLOWstandardsP2Widget classes missing a const constructor
layer_violationHIGHarchitectureP0Importing across forbidden architecture layersarchitecture.layers *
module_violationHIGHarchitectureP0Importing across forbidden business modulesarchitecture.modules *
circular_dependencyMEDIUMarchitectureP1File-level import cyclesarchitecture.detect_cycles *
device_lifecycleHIGHarchitectureP0Unbalanced init/teardown pairs (initState↔dispose, connect↔disconnect, etc.)
mqtt_connectionHIGHarchitectureP0MQTT connect/disconnect pairing, hardcoded broker URLs
iot_securityHIGHarchitectureP0Hardcoded credentials, cleartext MQTT/HTTP, insecure BLErules.iot_security.requireTls
ble_scanningMEDIUMarchitectureP1BLE startScan/stopScan pairing, scan timeoutrules.ble_scanning.maxScanDurationMs
pubspec_securityMEDIUMstandardsP2Unbounded deps, deprecated packages, outdated IoT dependencies

* Requires explicit YAML configuration to activate.


Output

Terminal table (default)

Colored terminal report grouped by domain. Shows overall score, file count, issue count, and per-issue detail.

JSON report

--format json writes .flutterguard/report.json under the output directory.

Example shape:

{
"version": "1.0.0",
"generatedAt": "2026-06-09T12:00:00.000Z",
"projectPath": "/path/to/project",
"score": 85,
"summary": {
"total": 3,
"high": 1,
"medium": 1,
"low": 1,
"suppressed": 0,
"suppressedByBaseline": 0,
"byDomain": {
"architecture": { "high": 1, "medium": 0, "low": 0, "total": 1 }
}
},
"issues": []
}

SARIF report

--format sarif writes .flutterguard/report.sarif for GitHub Code Scanning. High, medium, and low map to SARIF error, warning, and note.

Suppression and baseline

Use source suppression for known false positives:

// flutterguard: ignore missing_const_constructor// flutterguard: ignore iot_security, mqtt_connection// flutterguard: ignore all

Suppression applies only to the comment line and the following line.

Recommended CI adoption order:

flutterguard config doctor
flutterguard baseline create .
flutterguard baseline check . --baseline .flutterguard/baseline.json --no-growth
flutterguard scan . --baseline .flutterguard/baseline.json --format json --fail-on high

Scoring

score = max(0, 100 - high×10 - medium×4 - low×1)
ScoreRating
80–100Excellent
50–79Needs review
0–49Needs action

CI Integration

GitHub Actions

name: FlutterGuardon: [push, pull_request]jobs:
scan:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]runs-on: ${{ matrix.os }}steps:
- uses: actions/checkout@v4
- uses: dart-lang/setup-dart@v1with:
sdk: 3.3.0
- name: Install FlutterGuardrun: dart pub global activate flutterguard_cli
- name: Scanrun: flutterguard scan . --format json --baseline .flutterguard/baseline.json --fail-on high --min-score 80

GitHub Code Scanning

name: FlutterGuard SARIFon: [push, pull_request]jobs:
code-scanning:
runs-on: ubuntu-latestpermissions:
security-events: writecontents: readsteps:
- uses: actions/checkout@v4
- uses: dart-lang/setup-dart@v1with:
sdk: 3.3.0
- run: dart pub global activate flutterguard_cli
- run: flutterguard scan . --format sarif --baseline .flutterguard/baseline.json
- uses: github/codeql-action/upload-sarif@v3with:
sarif_file: .flutterguard/report.sarif

GitLab CI

flutterguard:
image: dart:3.3.0script:
- dart pub global activate flutterguard_cli
- flutterguard scan . --format json --fail-on high --min-score 80artifacts:
paths:
- .flutterguard/report.jsonwhen: always

pre-commit hook

# .pre-commit-config.yamlrepos:
- repo: localhooks:
- id: flutterguardname: FlutterGuard scanentry: flutterguard scan . --fail-on highlanguage: systempass_filenames: falsealways_run: true

Local scripts

macOS / Linux
#!/usr/bin/env bash# scan_ci.shif flutterguard scan . --format json --fail-on high --min-score 80;thenecho"All checks passed!"else
status=$?echo"FlutterGuard failed with exit code $status."exit"$status"fi
Windows (PowerShell)
# scan_ci.ps1$ErrorActionPreference="Stop"
flutterguard scan .--format json --fail-on high --min-score 80$status=$LASTEXITCODEif ($status-eq0) {
Write-Host"All checks passed!"-ForegroundColor Green
} else {
Write-Host"FlutterGuard failed with exit code $status."-ForegroundColor Red
exit$status
}

Troubleshooting

Windows: ANSI colors show as raw escape codes

Use Windows Terminal (built into Windows 10/11) instead of legacy cmd.exe. Alternatively, add --no-color to disable ANSI output:

flutterguard scan .--no-color

Windows: "API key required" error

This means the shell is resolving an old globally-installed binary instead of this repository's static-analysis CLI. Run the local binary directly:

.\flutterguard.exe scan .

Or reinstall:

dart pub global deactivate flutterguard_cli
dart pub global activate flutterguard_cli

Windows: garbled Chinese output

# In PowerShell, set UTF-8 output encoding
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
# Or use Windows Terminal (recommended) which defaults to UTF-8

Glob patterns: always use forward slashes

In flutterguard.yaml, use / for all path patterns regardless of platform:

# Correctpath: lib/presentation/**# Wrong (even on Windows)path: lib\presentation\**

Repository Layout

flutterguard/
├── packages/
│ └── flutterguard_cli/ Active CLI implementation
├── archive/ Frozen legacy runtime-tracing packages
└── examples/
└── scan_demo/ Demo scan target

Development

# All platforms
git clone https://github.com/lizy-coding/flutterguard.git
cd flutterguard
dart pub get
dart pub global activate melos
melos bootstrap
# Common commands
dart run melos run analyze # Static analysis
dart run melos run test:cli # Run tests
dart compile exe packages/flutterguard_cli/bin/flutterguard.dart -o flutterguard

Further Reading

DocumentContent
docs/USAGE.mdFull usage guide (all platforms)
docs/WINDOWS_ASSESSMENT.mdWindows compatibility assessment
docs/FLUTTERGUARD_SPEC.mdTechnical specification
docs/ARCHITECTURE.mdArchitecture overview

License

MIT

About

flutter project analyze plugin

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages