The ultimate concurrent Flutter workspace cleaner and package syncer.
flsweep is a high-performance, cross-platform CLI tool written in pure Dart.
It scans any workspace for Flutter projects, batch-runs flutter clean,
deep-cleans stubborn native build artifacts, and immediately restores
dependencies with flutter pub get β so your IDE symbols and indices come
back instantly. Every byte recovered is measured and reported.
$ flsweep ~/dev --all --deep -c 8
Flutter projects discovered: 12
Sweeping 12 projects
β shop_app freed 1.21 GB
β tracker freed 312.4 MB
β legacy_client flutter clean failed (exit 1): ...
β portfolio freed 890.7 MB
...
Sweep summary
β Freed 2.45 GB β 11 ok, 1 failed.
- Parallel execution β a bounded async worker pool cleans up to
--concurrentprojects at once (default: 4). - Zero-break sync β
flutter cleanβflutter pub getrun back-to-back per project, so every project stays buildable and IDE-friendly. - Deep clean (
--deep) β wipes whatflutter cleanleaves behind:android/.gradle,ios/Pods,ios/Podfile.lock, and.dart_tool. - Exact disk metrics β recursive size calculation (B/KB/MB/GB) before and after cleaning; the summary reports precisely what was recovered.
- Dual interface β an interactive multi-select checklist with live braille
spinners, and a fully non-interactive headless mode for CI/CD and AI
agents (
--all --quiet). - Error isolation β one broken project never aborts the run. Failures are logged, the remaining projects keep processing, and the exit code signals the outcome to CI.
- Instant startup β the recommended install is a standalone native
executable:
--helpand--versionrespond in milliseconds, and no Dart SDK messages ever appear at runtime.
Install the latest prebuilt native binary for your OS and architecture β no Dart SDK required, no cloning needed:
curl -fsSL https://raw.githubusercontent.com/MotiurRahmanSany/flsweep/main/install.sh | bashThe script auto-detects Linux/macOS and x64/ARM, downloads the matching
release artifact, and drops the binary on your PATH. Set
FLSWEEP_INSTALL_DIR to install somewhere other than ~/.local/bin.
Grab the latest flsweep from the Releases
page, pick the archive for your platform, and put the binary on your PATH:
tar -xzf flsweep-<version>-linux-x64.tar.gz
sudo install -m 0755 flsweep /usr/local/bin/Build once with any Dart SDK β₯ 3.0, then run without Dart entirely:
git clone <your-fork-url> flsweep
cd flsweep
tool/install.sh # compiles build/flsweep, installs to ~/.local/binThe result is a standalone binary that starts instantly and never prints SDK
messages like *"Resolving dependenciesβ¦", "Downloading packagesβ¦", or
"Building package executablesβ¦" β not even on a fresh machine. Set
FLSWEEP_INSTALL_DIR to install somewhere other than ~/.local/bin.
Prefer
dart run? It works, but on a fresh clone (or after dependency changes) the Dart toolchain may print those messages first. They come from the Dart SDK before flsweep starts, so no tool or flag can suppress them β the native build is the fix.
git clone <your-fork-url> flsweep
cd flsweep
dart pub get
dart pub global activate --source path .After global activation, flsweep is available on your PATH.
dart run bin/flsweep.dart [path] [flags]flsweep [path] [flags]
The first positional argument, if given, overrides --path.
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--path |
-p |
String | ./ |
Root path to start scanning for Flutter projects. |
--all |
-a |
Bool | false |
Non-interactive mode; process all found projects immediately. |
--deep |
-d |
Bool | false |
Deep clean mode; removes android/.gradle, ios/Pods, .dart_tool. |
--exclude |
-e |
String | "" |
Comma-separated paths or names to ignore during scan. |
--dry-run |
-n |
Bool | false |
Scan and display cleanable storage size without deleting anything. |
--concurrent |
-c |
Int | 4 |
Maximum number of projects to clean in parallel. |
--quiet |
-q |
Bool | false |
Suppress spinners/TUI animations; output minimal plain text. |
--verbose |
-v |
Bool | false |
Show additional command output. |
--help |
-h |
Bool | false |
Print usage information. |
--version |
Bool | false |
Print the tool version. |
Preview how much space a workspace could reclaim β touches nothing:
flsweep ~/dev --dry-runClean everything in a workspace, quietly, for a CI cron job:
flsweep ~/workspaces --all --quietDeep clean with 8 parallel workers, skipping a legacy monorepo and vendor dirs:
flsweep ~/dev --all --deep -c 8 --exclude legacy_monorepo,vendoredPoint at a single project and interactively confirm:
flsweep ~/dev/my_appRestore dependencies only, without cleaning:
# flsweep always runs pub get after clean; use --dry-run first to audit.
flsweep ~/dev --all| Code | Meaning |
|---|---|
0 |
Success (including a clean dry run). |
1 |
At least one project failed during the sweep (the rest still completed). |
64 |
Invalid command-line usage. |
66 |
The given path does not exist. |
70 |
An unexpected internal error. |
flsweep/
βββ bin/
β βββ flsweep.dart # CLI entry point, flag parsing, and route dispatching
βββ lib/
β βββ flsweep.dart # Public library entry
β βββ src/
β βββ models/
β β βββ project_info.dart # Data model for discovered projects
β βββ services/
β β βββ scanner.dart # Workspace file crawler & filtering engine
β β βββ executor.dart # Process runner (clean, pub get, deep clean)
β β βββ metrics.dart # Disk space calculator (KB/MB/GB)
β βββ ui/
β βββ tui.dart # Interactive multi-select & terminal prompts
β βββ spinner.dart # Animated terminal braille spinners
β βββ logger.dart # Colorized log formatters
βββ test/ # Unit tests for scanner, executor, and metrics
- Scan (
scanner.dart) β a breadth-first crawler walks the workspace from--path, skipping.pub-cache,.git,node_modules,build,.dart_tool, other dotted directories, and anything passed to--exclude. A directory is a Flutter project iff itspubspec.yamlhas a top-levelname:and a top-levelflutter:block. Nested traversal stops at each discovered project. - Measure (
metrics.dart) β for every project, the sizes ofbuild,.dart_tool,android/.gradle,ios/Pods, andios/Podfile.lockare summed recursively (symlinks are never followed). - Select (
tui.dart+checklist.dart) β interactive arrow-key checklist withatoggle-all (a first-party component built ondart_console), or zero prompts with--all/--quiet. - Execute (
executor.dart) β a fixed-size async worker pool runs, per project:flutter cleanβ (optional deep clean) βflutter pub get, then re-measures. Results preserve input order; every failure is captured per project. - Report (
logger.dart,tui.dart) β live spinner progress, per-project outcomes, and a final summary with total storage freed.
- Never touches
.pub-cacheor any system/SDK directory β the scanner hard-ignores it, and the deep-clean deleter re-validates every path against a whitelist (build,.dart_tool,.gradle,Pods,Podfile.lock) and a canonical containment check against the project root. - Deep-clean whitelist β a path is only deletable if it is (a) inside the
canonical project root, (b) exactly one of the whitelisted artifact names,
(c) not the project root, home directory, or filesystem root, and (d) not
under any
.pub-cachesegment. - No symlink following β neither size measurement nor deletion follows links, so linked artifacts elsewhere on disk are never affected.
- Crash-proof β
mainhas a final safety net; per-project failures are converted into status/exit codes, never stack traces.
dart pub get # fetch dependencies
dart analyze # static analysis β zero issues expected
dart test # run the full test suite
tool/build.sh # compile a standalone native executable to build/flsweepThe executor's process runner and delete routine are injectable seams, so the test suite exercises the full pipeline (ordering, concurrency caps, failure isolation, deep-clean safety) without a Flutter SDK on the machine.
| Package | Purpose |
|---|---|
args |
CLI flag parsing |
dart_console |
Raw terminal/key input for the interactive checklist |
mason_logger |
Logger baseline utilities |
path |
Cross-platform path handling everywhere |
Issues and pull requests are welcome. Please run dart analyze and
dart test before submitting; both must be clean.
Released under the MIT License β Β© 2026 Motiur Rahman Sany.