flutter_pruner 1.7.0
flutter_pruner: ^1.7.0 copied to clipboard
Safety-first semantic auditor for Dart and Flutter. Finds unreachable declarations, unused assets, and duplicate files with reversible cleanup.
Flutter Pruner #
Safety-first semantic cleanup for Dart and Flutter.
Find unreachable Dart declarations, assets, and other supported resources;
review the evidence, then apply only changes allowed by the configured safety
policy.
📦 Install #
Requires Dart SDK 3.9 or newer.
dart pub global activate flutter_pruner
✨ What it finds #
Six built-in analyzers share one reachability graph, so cross-domain chains (e.g. a route referencing an asset referenced from Dart) are resolved together:
| Analyzer | Finds |
|---|---|
| 📝 Dart declarations | Unreachable libraries, declarations, unused imports |
| 🖼️ Assets | Declared asset families with no resolved reference |
| 📑 Duplicates | Byte-identical files that could be unified |
| 🧭 GoRouter routes | Routes unreachable from any entry point |
| 💉 GetIt registrations | DI registrations never resolved |
| 🌍 Localization | Unused ARB keys and generated l10n dead code |
Every finding carries a confidence tier and the evidence behind it — the explanation is the product, not a score.
🛡️ Confidence tiers #
| Tier | Meaning | Can apply? |
|---|---|---|
SAFE |
Every safety predicate holds | ✅ Yes |
HIGH |
All hard gates hold, one known manual risk | ⚠️ Package-internal only, with confirmation |
REVIEW |
Evidence incomplete or ambiguous | ❌ Never |
PROTECTED |
Must be kept (framework wiring, entry points) | ❌ Never |
PROTECTED always wins. Most findings on a mature codebase land in HIGH or
REVIEW — that is the intended outcome, not a limitation.
🚀 Four commands #
flutter_pruner init # declare project boundary and targets
flutter_pruner scan # analyze, save report, change nothing
flutter_pruner apply --dry-run # preview the plan, change nothing
flutter_pruner apply # quarantine originals, mutate, verify
To undo: flutter_pruner rollback <run-id>.
See the 5-minute quickstart for a complete walkthrough.
🔄 Apply and recover #
A mutating run is all-or-nothing: originals are quarantined before editing, the project is rescanned and verified after mutation, and everything is restored if any step fails.
flutter_pruner quarantine list
flutter_pruner quarantine inspect <run-id>
flutter_pruner rollback <run-id>
Read how the workflow works before applying to an important project.
⚠️ Safety in one box #
- Start from a clean Git worktree. Rollback is a recovery layer, not a replacement for version control.
- Review
.flutter_pruner/config.yaml. Coverage is declared by you, never inferred. - Scan exits 0 even with findings. Inspect the report, not the exit code.
- Stop on
recoveryRequired. Inspect quarantine before running anything else.
📊 Reports #
Every completed scan saves one immutable report under
.flutter_pruner/reports/. HTML is the default and works offline — open the
path printed at the end of the run.
For CI, save JSON and inspect tiers — never parse human stdout:
flutter_pruner scan --format json --output scan.json
jq -e '
.run.status == "completed" and
.statistics.findings.byTier.SAFE == 0 and
.statistics.findings.byTier.HIGH == 0
' .flutter_pruner/reports/scan.json
⚙️ Configuration #
flutter_pruner init writes .flutter_pruner/config.yaml — the declared
analysis boundary:
version: 1
analysis:
mode: application # application | package | package-internal
target_matrix:
complete: true
targets:
- name: android-prod
platform: android
entrypoint: lib/main.dart
Three modes: application (closed app, SAFE may apply), package
(external consumers unknown, audit-only), package-internal (local package
evaluation, SAFE plus one allowlisted HIGH with confirmation).
See every config field.
📚 Documentation #
Technical architecture, report storage, performance, and release-validation notes remain repository-only deep dives.
Found a false SAFE finding, data loss, or broken rollback? Open an
issue — these are
release-blocking defects.
🤝 Contributing #
New domains land as adapters in lib/src/adapters/ — see
how to add an adapter.
Core reachability and confidence logic stays domain-agnostic.
📄 License #
MIT — see LICENSE.