I've found myself working on several projects at once sometimes 4 or 5 different apps in a single week. Flutter has been a revelation for cross platform development. It has, however, one persistent irritation: the ever growing build folders that take up a lot of disk space.
If you're anything like me, you've had that moment when your disk space warning goes off, and you find that your Flutter projects are the ones to blame, with not just one or two but several gigabytes of cached builds silently piling up over time. In this article, I'll walk you through the steps of how I solved this problem for myself by creating what I think of as a simple but powerful Dart command-line tool that can automatically clean up Flutter projects in my various development directories.
The Problem: Flutter's Hungry Build Folders
The build process of Flutter generates a significant number of intermediate files, compiled code, and assets in the build directory of each project. These files are essential during the development and build stages, but they can be safely cleaned up when not in active use.
The build directory for a single Flutter project can easily swell to hundreds of megabytes or even several gigabytes, especially when you're building for multiple platforms. Working on several projects, of course, adds to this number even more. All told, we could be looking at significant disk space usage.
Flutter gives a simple opportunity to clean a project by offering the flutter clean command, which removes the build directory and frees up the occupied space.
Yet the need to clean projects becomes apparent when one has many projects scattered throughout their developer folders and attempts to navigate to each folder just to run the clean command.
The Solution: A Dart CLI Tool for Automated Cleaning
Jamalianpour
/
f_cleaner
A CLI tool to scan directories for Flutter projects and run 'flutter clean' to free up disk space.
Flutter Cleaner (f_cleaner) 🧹
A Dart CLI tool that automatically scans directories for Flutter projects and runs flutter clean
to free up disk space.
The Problem
Flutter projects accumulate large build directories that consume significant disk space. Manually cleaning each project becomes tedious when you're working on multiple projects.
The Solution
This tool automatically:
- Scans directories to identify Flutter projects
- Calculates build directory sizes
- Runs
flutter clean
on each project - Reports total space freed
Installation
You can install flutter cleaner CLI from github repository or pub.dev:
# From Github
dart pub global activate -sgit https://github.com/Jamalianpour/f_cleaner.git
# From Pub.dev
dart pub global activate f_cleaner
Or install and active it from source code:
# Clone the repository
git clone https://github.com/yourusername/f_cleaner.git
cd f_cleaner
# Install dependencies
dart pub get
# Activate the CLI tool globally
dart pub global activate --source path .
Usage
# Clean Flutter projects in current directory and subdirectories
f_cleaner
…To solve this problem efficiently, I created a Dart CLI application that:
- Scans specified directories (recursively by default)
- Identifies Flutter projects by detecting the presence of a pubspec.yaml file with Flutter dependencies
- Calculates the size of each project's build directory
- Runs flutter clean on each identified project
- Reports on the total space saved
This approach allows me to clean all my Flutter projects with a single command, saving both time and disk space.
Building the CLI Tool
Let's walk through the key components of this solution. Our Dart CLI application consists of two main files: the main Dart code and a pubspec.yaml file for dependencies.
Setting Up the Project
First, I created a new Dart project with the necessary dependencies:
name: f_cleaner
description: A CLI tool to scan directories for Flutter projects and run 'flutter clean' to free up disk space.
version: 1.0.0
environment:
sdk: '>=3.0.0 <4.0.0'
dependencies:
args: ^2.6.0
path: ^1.9.1
dev_dependencies:
lints: ^2.1.0
test: ^1.24.0
executables:
f_cleaner: f_cleaner
The args
package provides command-line argument parsing capabilities, while path helps with cross-platform path
manipulation.
The Core Functionality
The main code is organized into several key functions:
- Argument Parsing: Handling command-line options for directory selection, recursive scanning, and verbosity
- Flutter Project Detection: Identifying valid Flutter projects
- Directory Scanning: Recursively exploring directories
- Size Calculation: Determining how much space will be freed
- Running Flutter Clean: Executing the command and handling results
Here's a simplified breakdown of the key logic:
Future<bool> _isFlutterProject(String dirPath) async {
// Check for pubspec.yaml file
final pubspecFile = File(path.join(dirPath, 'pubspec.yaml'));
if (!await pubspecFile.exists()) {
return false;
}
// Read pubspec.yaml and check for Flutter dependency
try {
final content = await pubspecFile.readAsString();
return content.contains('flutter:') || content.contains('sdk: flutter');
} catch (_) {
return false;
}
}
Future<int> _calculateDirectorySize(Directory dir) async {
if (!await dir.exists()) {
return 0;
}
int size = 0;
try {
await for (final entity in dir.list(recursive: true, followLinks: false)) {
if (entity is File) {
size += await entity.length();
}
}
} catch (_) {
// Ignore errors
}
return size;
}
Future<ProcessResult> _runFlutterClean(String projectDir, {required bool verbose}) async {
if (verbose) {
print('Running flutter clean in $projectDir');
}
return await Process.run(
'flutter',
['clean'],
workingDirectory: projectDir,
runInShell: true,
);
}
The main scanning function coordinates these operations and collects the results:
Future<CleanResults> scanAndCleanFlutterProjects(
String rootDirPath, {
required bool recursive,
required bool verbose,
}) async {
final rootDir = Directory(rootDirPath);
if (!await rootDir.exists()) {
throw Exception('Directory does not exist: $rootDirPath');
}
int projectsFound = 0;
int projectsCleaned = 0;
int spaceFreed = 0;
final futures = <Future>[];
await for (final entity in _listDirectories(rootDir, recursive: recursive)) {
if (await _isFlutterProject(entity.path)) {
projectsFound++;
if (verbose) {
print('Found Flutter project at: ${entity.path}');
}
final buildDir = Directory(path.join(entity.path, 'build'));
final future = _calculateDirectorySize(buildDir).then((size) async {
if (size > 0) {
try {
final result = await _runFlutterClean(entity.path, verbose: verbose);
if (result.exitCode == 0) {
projectsCleaned++;
spaceFreed += size;
print('✓ Cleaned: ${entity.path} (freed ${_formatSize(size)})');
} else {
print('✗ Failed to clean: ${entity.path}');
if (verbose) {
print(' Error: ${result.stderr}');
}
}
} catch (e) {
print('✗ Error cleaning: ${entity.path}');
if (verbose) {
print(' Error: $e');
}
}
} else if (verbose) {
print('• Skipped: ${entity.path} (no build directory or empty)');
}
});
futures.add(future);
}
}
await Future.wait(futures);
return CleanResults(
projectsFound: projectsFound,
projectsCleaned: projectsCleaned,
spaceFreed: spaceFreed,
);
}
One key optimization in this design is the use of parallel processing with futures. Instead of cleaning each project sequentially, the tool launches multiple cleaning operations concurrently, making the process much faster, especially when dealing with many projects.
Using the Tool
With the CLI tool complete, usage is straightforward. After installation, it can be run with various options:
# Clean all Flutter projects in current directory and subdirectories
f_cleaner
# Clean Flutter projects in a specific directory
f_cleaner --dir=/path/to/your/flutter/projects
# Non-recursive scan (only check the specified directory)
f_cleaner --dir=/path/to/your/flutter/projects --no-recursive
# Show detailed output
f_cleaner --verbose
The tool provides a clear summary after execution:
Flutter Projects Cleaner 🧹
==========================
Scanning directory: /Users/username/development
Recursive scan: Yes
✅ Cleaned: /Users/username/development/project1 (freed 2.3 GB)
✅ Cleaned: /Users/username/development/project2 (freed 1.8 GB)
✅ Cleaned: /Users/username/development/clients/project3 (freed 3.2 GB)
❌ Failed to clean: /Users/username/development/broken_project
Summary
-------
Flutter projects found: 4
Projects cleaned: 3
Approximate space freed: 7.3 GB
Time taken: 5 seconds
Benefits and Results
After implementing this tool in my workflow, I've experienced several benefits:
- Significant space savings: Regularly recovering 10–20GB of disk space
- Time efficiency: What used to take manual effort now happens automatically
- Better organization: I no longer avoid cleaning projects due to the hassle
- Development speed: Less time fighting with disk space warnings means more time coding
I've been running this tool as part of my weekly maintenance routine, and it has become an essential part of my Flutter development workflow.
Conclusion
As Flutter developers, we often focus on building great apps and overlook infrastructure improvements that can enhance our development experience. This simple CLI tool demonstrates how a small investment in automation can solve persistent annoyances and improve productivity.
The complete source code for this tool is available in the GitHub repository: f_cleane (feel free to contribute or customize it for your needs).
If you're a Flutter developer managing multiple projects, I encourage you to try this approach or build your own version. The few minutes spent setting up automation will save hours of manual work and gigabytes of disk space in the long run.
Top comments (0)