IoT Flutter project static analysis CLI for architecture enforcement, code quality, and CI gating.
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
- 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
- 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
- Dart SDK 3.3.0 or newer
melosfor workspace bootstrap when running from source- Supported OS: macOS, Windows, Linux
macOS / Linux
dart pub global activate flutterguard_cli
# Verify
flutterguard --versionEnsure $HOME/.pub-cache/bin is on your PATH:
export PATH="$PATH:$HOME/.pub-cache/bin"# add to ~/.zshrc or ~/.bashrcWindows (PowerShell)
dart pub global activate flutterguard_cli
# Verify
flutterguard --versionIf 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"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 .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 .# 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 --helpflutterguard scan examples/scan_demoCommands:
| Command | Description |
|---|---|
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 stats | Show baseline fingerprint counts |
flutterguard baseline prune [<path>] | Remove fixed issues from a baseline |
flutterguard baseline check [<path>] --no-growth | Fail when current issues are missing from baseline |
flutterguard doctor install | Diagnose executable version and PATH conflicts |
flutterguard init | Create a starter flutterguard.yaml |
flutterguard init --profile migration | Create a starter config from a profile |
flutterguard init --with-architecture | Create config with architecture layer/module templates |
flutterguard config print | Print the merged effective configuration |
flutterguard config doctor | Validate config, globs, and architecture references |
flutterguard issue export | Export one issue as a local feedback JSON bundle |
flutterguard rules | List available rules |
flutterguard explain <rule-id> | Explain one rule |
flutterguard --help / -h | Show usage |
flutterguard --version / -V | Show version |
| Flag | Short | Default | Description |
|---|---|---|---|
<path> | — | . | Positional project path (optional, before options) |
--path | -p | . | Project path to scan (overridden by positional <path>) |
--config | -c | flutterguard.yaml | Config file path |
--format | -f | table | Output format: table, json, or sarif |
--output | -o | .flutterguard | Output directory for reports |
--verbose | -v | off | Show detailed output with code context |
--no-color | — | off | Disable ANSI terminal colors |
--changed-only | — | off | Only scan Dart files changed since --base |
--base | — | main | Git base ref for --changed-only |
--baseline | — | unset | Baseline JSON file used to hide existing issues |
--fail-on | — | none | CI gate: none / high / medium / low |
--min-score | — | unset | Minimum score threshold 0–100 |
--help | -h | — | Show scan usage |
| Code | Meaning |
|---|---|
0 | Success, including help/version and a changed-only scan with no relevant changes |
1 | CI gate failed (issues at/above --fail-on level, or score below --min-score) |
2 | Scan setup error (bad path, missing explicit config, invalid config, or no configured Dart files) |
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:
- Absolute paths are used as-is and must exist.
- Relative paths are resolved from the target project root, never from CWD.
- An omitted default
flutterguard.yamluses built-in defaults; any explicitly selected config must exist.
Create flutterguard.yaml in your project root.
Recommended strategy:
- Start with zero config:
flutterguard scan. - Run
flutterguard initwhen you need custom thresholds or excludes. - Use
flutterguard config printto inspect merged defaults. - Use
flutterguard config doctorbefore enabling CI gates. - Add architecture layers/modules only after project boundaries are agreed.
For the full decision model, see Configuration Strategy.
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# ... 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: trueImportant: Architecture rules (
layer_violation,module_violation,circular_dependency) require explicitarchitecture.layers,architecture.modules, and/orarchitecture.detect_cyclesdeclarations 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.
| Rule ID | Level | Domain | Priority | What it checks | Config required |
|---|---|---|---|---|---|
large_file | LOW | standards | P2 | File line count over maxLines | — |
large_class | LOW | standards | P2 | Class body line count over maxLines | — |
large_build_method | MEDIUM | performance | P1 | build() method line count over maxLines | — |
lifecycle_resource_not_disposed | MEDIUM | performance | P1 | Undisposed StreamSubscription, Timer, AnimationController, TextEditingController, ScrollController, FocusNode, MqttClient, BluetoothDevice, StreamController | — |
missing_const_constructor | LOW | standards | P2 | Widget classes missing a const constructor | — |
layer_violation | HIGH | architecture | P0 | Importing across forbidden architecture layers | architecture.layers * |
module_violation | HIGH | architecture | P0 | Importing across forbidden business modules | architecture.modules * |
circular_dependency | MEDIUM | architecture | P1 | File-level import cycles | architecture.detect_cycles * |
device_lifecycle | HIGH | architecture | P0 | Unbalanced init/teardown pairs (initState↔dispose, connect↔disconnect, etc.) | — |
mqtt_connection | HIGH | architecture | P0 | MQTT connect/disconnect pairing, hardcoded broker URLs | — |
iot_security | HIGH | architecture | P0 | Hardcoded credentials, cleartext MQTT/HTTP, insecure BLE | rules.iot_security.requireTls |
ble_scanning | MEDIUM | architecture | P1 | BLE startScan/stopScan pairing, scan timeout | rules.ble_scanning.maxScanDurationMs |
pubspec_security | MEDIUM | standards | P2 | Unbounded deps, deprecated packages, outdated IoT dependencies | — |
* Requires explicit YAML configuration to activate.
Colored terminal report grouped by domain. Shows overall score, file count, issue count, and per-issue detail.
--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": []
}--format sarif writes .flutterguard/report.sarif for GitHub Code Scanning. High, medium, and low map to SARIF error, warning, and note.
Use source suppression for known false positives:
// flutterguard: ignore missing_const_constructor// flutterguard: ignore iot_security, mqtt_connection// flutterguard: ignore allSuppression 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 highscore = max(0, 100 - high×10 - medium×4 - low×1)
| Score | Rating |
|---|---|
| 80–100 | Excellent |
| 50–79 | Needs review |
| 0–49 | Needs action |
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 80name: 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.sarifflutterguard:
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-config.yamlrepos:
- repo: localhooks:
- id: flutterguardname: FlutterGuard scanentry: flutterguard scan . --fail-on highlanguage: systempass_filenames: falsealways_run: truemacOS / 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"fiWindows (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
}Use Windows Terminal (built into Windows 10/11) instead of legacy cmd.exe. Alternatively, add --no-color to disable ANSI output:
flutterguard scan .--no-colorThis 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# In PowerShell, set UTF-8 output encoding
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
# Or use Windows Terminal (recommended) which defaults to UTF-8In flutterguard.yaml, use / for all path patterns regardless of platform:
# Correctpath: lib/presentation/**# Wrong (even on Windows)path: lib\presentation\**flutterguard/
├── packages/
│ └── flutterguard_cli/ Active CLI implementation
├── archive/ Frozen legacy runtime-tracing packages
└── examples/
└── scan_demo/ Demo scan target
# 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| Document | Content |
|---|---|
| docs/USAGE.md | Full usage guide (all platforms) |
| docs/WINDOWS_ASSESSMENT.md | Windows compatibility assessment |
| docs/FLUTTERGUARD_SPEC.md | Technical specification |
| docs/ARCHITECTURE.md | Architecture overview |
MIT