Architecture health check for Flutter apps.
Flutter ScaleGuard is a deterministic CLI tool that detects architectural risks in Flutter projects before they become expensive to fix.
Instead of focusing on style or formatting, ScaleGuard analyzes structural architecture patterns such as:
- cross-feature coupling
- layer boundary violations
- service locator abuse
- module hotspots
- configuration risks
It helps teams detect architecture erosion early, before it slows development.
Install the CLI:
dart pub global activate scale_guardRun a scan in your Flutter project:
scale_guard scan .Flutter ScaleGuard v0.6.0
Project: ./my_flutter_app
Scan Path: ./my_flutter_app
Architecture Score: 69/100
Risk Level: Medium
Summary:
This codebase shows early-stage coupling patterns that may reduce feature isolation as the team scales.
Dominant Risk Category: Coupling Risk (69% of total penalty)
Most Expensive Risk: Feature Module Imports Another Feature (reduces isolation and scaling flexibility) (-15.0) [Coupling Risk] [rule: cross_feature_coupling]
Hotspot (source): lib/features/user_profile (42 findings)
Examples:
lib/features/user_profile/domain/usecase.dart lib/features/dashboard/repo.dart
(+39 more)
---
Top Fix Priorities:
1. lib/features/user_profile
- 42 findings
- dominant: cross_feature_coupling
- Avoid direct feature-to-feature imports.
2. lib/features/dashboard
- 28 findings
- dominant: cross_feature_coupling
- Avoid direct feature-to-feature imports.
Hotspots:
lib/features/user_profile (42 findings)
- cross_feature_coupling: 38
- service_locator_abuse: 4
lib/features/dashboard (28 findings)
- cross_feature_coupling: 22
- hardcoded_scale_risks: 6
---
Findings by Category:
Coupling Risk
- Feature Module Imports Another Feature (91 across 31 files)
Features importing each other directly increases coupling and reduces scalability.
Suggestion: Avoid direct feature-to-feature imports. Move shared contracts into a shared domain layer or introduce an abstraction.
- Global Dependency Access Across Boundaries (34 across 15 files)
Global dependency access hides dependencies and reduces architectural clarity.
Suggestion: Limit service locator usage to composition roots. Inject dependencies explicitly into classes.
---
Tip:
Use ScaleGuard in CI to prevent architecture drift:
scale_guard scan . --fail-under 70
ScaleGuard can be used to prevent architectural regressions in CI pipelines.
Example:
scale_guard scan . --fail-under 70If the architecture score drops below the threshold, the command exits with a failure code.
This allows teams to enforce architecture quality gates automatically.
Global install via Dart:
dart pub global activate scale_guardOr run directly from the repository:
dart run bin/scale_guard.dart scan .Basic scan:
scale_guard scan .JSON output:
scale_guard scan . --jsonFail if architecture score is too low:
scale_guard scan . --fail-under 70ScaleGuard produces a structured report in this order:
Numeric score from 0–100. Higher score means lower architectural risk.
Risk classification based on score:
| Score | Risk Level |
|---|---|
| 80–100 | Low |
| 55–79 | Medium |
| 0–54 | High |
A short summary of the dominant risk category and its impact.
The architecture problem contributing most to the score penalty.
The single rule responsible for the largest score reduction, with optional hotspot (source/target) and example findings.
The top 3 modules (by finding count) with the most issues. For each, the report shows the path, total findings, the dominant rule, and a short actionable hint so you know where to start fixing.
Modules grouped by path, with total findings and a per-rule breakdown. Shows where violations concentrate so you can focus refactoring effort.
Findings grouped by risk category. For each rule, the report includes:
- Count and file spread
- A description of the problem
- A suggestion on how to fix it
A short tip at the end of the report on using ScaleGuard in CI to prevent architecture drift.
| Code | Meaning |
|---|---|
| 0 | Scan succeeded (and passed fail-under if set via --fail-under or scaleguard.yaml) |
| 1 | High risk (scan succeeded but risk level is High) |
| 2 | Scan succeeded but fail-under threshold not met (CLI or config) |
| 64 | Invalid usage / invalid project path (e.g., not a directory) |
Add an optional scaleguard.yaml file in the project root. Partial config is fine; missing keys use defaults. See scaleguard.yaml.example for a commented template.
Precedence: scaleguard.yaml is primary. Legacy risk_scanner.yaml remains supported. If both files exist, only scaleguard.yaml is loaded; risk_scanner.yaml is ignored and a warning is printed to stderr.
Fail-under: Set a minimum architecture score under score.fail_under (integer 0–100). The CLI flag --fail-under overrides the file when you pass it (same range).
Disabled rules: Under rules, set a rule id to false. Disabled rules are not run and are omitted from JSON ruleResults.
# Minimal example (all optional)
feature_roots:
- lib/features
ignore:
- lib/generated/**
- lib/l10n/**
rules:
god_files: false
service_locator_abuse: true
thresholds:
god_file_medium_loc: 500
god_file_high_loc: 900
score:
fail_under: 75ignore— Appended to built-in default ignore patterns (deduplicated).rules— Map of rule id →true/false. Omitted rules stay enabled.
Paths are project-relative (forward slashes), matching how files are indexed under lib/.
- Literal pattern — Does not contain
*. Matches if the path contains the pattern as a substring or ends with it (same idea as olderignored_patternsentries like.g.dartor/build/). - Glob pattern — Contains
*. Matching uses only glob rules (no extra substring pass for that entry):**matches zero or more path segments (between/).*matches zero or more characters inside one segment (does not cross/).
Examples: lib/generated/**, lib/l10n/**, **/*.g.dart.
You can still use risk_scanner.yaml alone. Keys include feature_roots, layer_mappings, ignored_patterns, god_file_medium_loc, god_file_high_loc, and others (see risk_scanner.yaml.example). ignored_patterns replaces the entire default ignore list when this file is loaded (unlike ignore in scaleguard.yaml, which merges with defaults).
ScannerConfig.load(projectPath)— Unchanged; warnings from parsing are discarded.ScannerConfig.loadWithDiagnostics(projectPath)— Returns({ScannerConfig config, List<String> warnings})for the same merge rules as the CLI.
ScaleGuard detects the following architecture risks. In the report, each rule includes a description (what’s wrong) and a suggestion (how to fix it).
Feature modules importing other feature modules. Suggestion: move shared contracts into a shared domain layer or introduce an abstraction.
Invalid dependencies between architecture layers (e.g. presentation → data). Suggestion: ensure domain does not depend on data or presentation; move implementations behind interfaces.
Files exceeding defined size thresholds. Suggestion: split into smaller focused components and separate responsibilities by layer or feature.
Configuration values embedded directly in code. Suggestion: move configuration to environment-based or external config files.
Global dependency access patterns. Suggestion: limit usage to composition roots and inject dependencies explicitly.
Shared modules importing feature modules. Suggestion: keep shared modules independent of features; depend on abstractions.
Direct route usage instead of centralized navigation. Suggestion: use a central router or navigation service.
ScaleGuard is intentionally designed to be:
Deterministic
Same code always produces the same result.
Fast
Scans large Flutter projects in seconds.
Opinionated
Focused specifically on architectural scale risks.
CLI-first
Simple tooling that integrates easily into CI pipelines.
ScaleGuard is useful when:
- preparing a Flutter app for scale
- auditing an existing codebase
- reviewing architecture health during development
- preventing architecture decay in CI
- identifying refactoring hotspots
Pavel Koifman
Mobile Strategy & Architecture for Founders
Creator of ScaleGuard – Flutter architecture health check.
- GitHub: https://github.com/PavelK2254
- LinkedIn: https://www.linkedin.com/in/pavel-koifman/
Apache License 2.0.
See the LICENSE file for details.
