A fast and efficient CLI tool for recursively cleaning Rust
target/, Node.jsnode_modules/, Python cache, and Govendor/directories to reclaim disk space.
Quick Start
# Install from crates.io
# Clean all development directories in current directory
# Preview what would be cleaned (dry run)
# Interactive mode - choose which projects to clean
Features
- Multi-language support: Clean Rust (
target/), Node.js (node_modules/), Python (cache dirs), and Go (vendor/) build artifacts - Parallel scanning: Lightning-fast directory traversal using multithreading
- Smart filtering: Filter by project size, modification time, and project type
- Interactive mode: Choose which projects to clean with an intuitive interface
- Dry-run mode: Preview what would be cleaned without actually deleting anything
- Progress indicators: Real-time feedback during scanning and cleaning operations
- Executable preservation: Keep compiled binaries before cleaning with
--keep-executables - Detailed statistics: See total space that can be reclaimed before cleaning
- Persistent configuration: Set defaults in
~/.config/clean-dev-dirs/config.tomlso you don't repeat flags - Flexible configuration: Combine multiple filters and options for precise control
Inspiration
This project is inspired by cargo-clean-all, a Rust-specific tool for cleaning cargo projects. We've improved upon the original concept with:
- Multi-language support: Extended beyond Rust to support Node.js, Python, and Go projects
- Parallel scanning: Significantly faster directory traversal using multithreading
- Enhanced filtering: More granular control over what gets cleaned
- Cleaner code architecture: Well-structured, modular codebase for better maintainability
Installation
From crates.io (Recommended)
From Source
Requirements
- Rust 2021 edition or later
- Cargo package manager
Usage
Basic Usage
# Clean all development directories in the current directory
# Clean a specific directory
# Preview what would be cleaned (dry run)
# Interactive mode - choose which projects to clean
Project Type Filtering
# Clean only Rust projects
# or use short flag
# Clean only Node.js projects
# Clean only Python projects
# Clean only Go projects
# Clean all project types (default)
Size and Time Filtering
# Only clean projects with build dirs larger than 100MB
# Only clean projects not modified in the last 30 days
# Combine size and time filters
Keeping Executables
# Preserve compiled binaries before cleaning
# or use short flag
# In interactive mode (-i) without -k, you will be prompted:
# "Keep compiled executables before cleaning? (y/N)"
# Combine with other options
When enabled, compiled outputs are copied to <project>/bin/ before the build directory is deleted:
- Rust: executables from
target/release/andtarget/debug/are copied tobin/release/andbin/debug/ - Python:
.whlfiles fromdist/and.so/.pydC extensions frombuild/are copied tobin/ - Node.js / Go: no-op (their cleaned directories contain dependencies, not build outputs)
Advanced Options
# Use 8 threads for faster scanning
# Show verbose output including scan errors
# Skip specific directories during scanning
# Non-interactive mode (auto-confirm)
# Combine multiple options
Configuration File
You can store default settings in a TOML file so you don't have to repeat the same flags every time. CLI arguments always override config file values.
Location: ~/.config/clean-dev-dirs/config.toml (Linux/macOS) or %APPDATA%\clean-dev-dirs\config.toml (Windows)
# Default project type filter
= "rust"
# Default directory to scan (~ is expanded)
= "~/Projects"
[]
= "50MB"
= 7
[]
= 4
= true
= [".cargo", "vendor"]
= [".git"]
[]
= true
= false
= false
All fields are optional — only set what you need. An absent config file is silently ignored; a malformed one produces an error message.
Layering rules:
| Value type | Behavior |
|---|---|
Scalar (keep_size, threads, project_type, dir, …) |
CLI wins if provided, otherwise config file, otherwise built-in default |
Boolean flag (--dry-run, --verbose, …) |
true if the CLI flag is present or the config file sets it to true |
List (skip, ignore) |
Merged — config file entries first, then CLI entries appended |
Examples:
# Uses keep_size = "50MB" from config, overrides project_type on CLI
# CLI --keep-size wins over the config file value
# skip dirs from config (.cargo, vendor) + CLI (node_modules) are all active
Common Use Cases
1. Clean old Rust projects:
2. Preview large Python cache directories:
3. Interactive cleaning of all Node.js projects:
4. Quick cleanup with confirmation:
5. Fast scan with multiple threads:
6. Clean Rust projects but keep the compiled binaries:
7. Set up a config file for your usual workflow:
# Now just run without flags — defaults come from the config
Command Reference
Main Arguments
| Argument | Description |
|---|---|
[DIR] |
Directory to search for projects (default: current directory) |
Project Type Filter
| Option | Short | Values | Description |
|---|---|---|---|
--project-type |
-p |
all, rust, node, python, go |
Filter by project type (default: all) |
Filtering Options
| Option | Short | Description |
|---|---|---|
--keep-size |
-s |
Ignore projects with build dir smaller than specified size |
--keep-days |
-d |
Ignore projects modified in the last N days |
Execution Options
| Option | Short | Description |
|---|---|---|
--yes |
-y |
Don't ask for confirmation; clean all detected projects |
--dry-run |
List cleanable projects without actually cleaning | |
--interactive |
-i |
Use interactive project selection |
--keep-executables |
-k |
Copy compiled executables to <project>/bin/ before cleaning |
Scanning Options
| Option | Short | Description |
|---|---|---|
--threads |
-t |
Number of threads for directory scanning (default: CPU cores) |
--verbose |
-v |
Show access errors during scanning |
--skip |
Directories to skip during scanning (can be specified multiple times) |
Size Formats
The --keep-size option supports various size formats:
| Format | Example | Description |
|---|---|---|
| Decimal | 100KB, 1.5MB, 2GB |
Base 1000 |
| Binary | 100KiB, 1.5MiB, 2GiB |
Base 1024 |
| Bytes | 1000000 |
Raw byte count |
Examples:
Project Detection
The tool automatically detects development projects by looking for characteristic files and directories:
Rust Projects
- Detection criteria: Both
Cargo.tomlandtarget/directory must exist - Cleans:
target/directory - Name extraction: From
[package] nameinCargo.toml
Node.js Projects
- Detection criteria: Both
package.jsonandnode_modules/directory must exist - Cleans:
node_modules/directory - Name extraction: From
namefield inpackage.json
Python Projects
- Detection criteria:
- At least one config file:
requirements.txt,setup.py,pyproject.toml,setup.cfg,Pipfile,pipenv.lock,poetry.lock - At least one cache/build directory exists
- At least one config file:
- Cleans: The largest cache/build directory among:
__pycache__.pytest_cachevenv/.venvbuild/dist.eggs/.tox/.coverage
- Name extraction: From
pyproject.toml(project name or tool.poetry name) orsetup.py
Go Projects
- Detection criteria: Both
go.modandvendor/directory must exist - Cleans:
vendor/directory - Name extraction: From module path in
go.mod
Safety Features
- Dry-run mode: Preview all operations before execution with
--dry-run - Interactive confirmation: Manually select projects to clean with
--interactive - Intelligent filtering: Skip recently modified or small projects with
--keep-daysand--keep-size - Error handling: Graceful handling of permission errors and inaccessible files
- Read-only scanning: Never modifies files during the scanning phase
- Clear output: Color-coded, human-readable output with project types and sizes
Output
The tool provides beautiful, colored output including:
| Icon | Project Type |
|---|---|
| 🦀 | Rust projects |
| 📦 | Node.js projects |
| 🐍 | Python projects |
| 🐹 | Go projects |
Sample Output
Found 15 projects
📊 Found projects:
🦀 my-rust-app (/home/user/projects/rust-app)
Size: 2.3 GB
📦 web-frontend (/home/user/projects/web-app)
Size: 856 MB
🐍 ml-project (/home/user/projects/python-ml)
Size: 1.2 GB
Total space that can be reclaimed: 4.4 GB
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Adding Language Support
Want to add support for a new programming language? Here's how to extend clean-dev-dirs:
1. Update Project Types
First, add your language to the ProjectType enum in src/project/project.rs:
Don't forget to update the Display implementation to include an appropriate emoji and name.
2. Add CLI Filter Option
Update src/config/filter.rs to add your language to the ProjectFilter enum:
3. Implement Project Detection
Add detection logic in src/scanner.rs by implementing:
- Detection method:
detect_your_language_project()- identifies projects by looking for characteristic files - Name extraction:
extract_your_language_project_name()- parses project configuration files to get the name - Integration: Update
detect_project()to call your detection method
Example detection criteria:
4. Update Directory Exclusions
Add any language-specific directories that should be skipped during scanning to the should_scan_entry() method in src/scanner.rs.
5. Update Documentation
- Add your language to the "Project Detection" section in this README
- Update the CLI help text descriptions
- Add examples in the usage section
6. Testing Considerations
Consider these when testing your implementation:
- Multiple config files: Some languages have different project file formats
- Build directory variations: Different build tools may use different directory names
- Name extraction edge cases: Handle malformed or missing project names gracefully
- Performance: Ensure detection doesn't significantly slow down scanning
7. Example Languages to Add
Some languages that would be great additions:
- C/C++: Look for
CMakeLists.txt/Makefile+build/orcmake-build-*/ - Java: Look for
pom.xml/build.gradle+target/orbuild/ - C#: Look for
*.csproj/*.sln+bin//obj/ - PHP: Look for
composer.json+vendor/ - Ruby: Look for
Gemfile+vendor/bundle/ - Swift: Look for
Package.swift+.build/
8. Pull Request Guidelines
When submitting your language support:
- Test thoroughly: Verify detection works with real projects
- Add examples: Include sample project structures in your PR description
- Update help text: Ensure all user-facing text is clear and consistent
- Follow patterns: Use the same patterns as existing language implementations
- Consider edge cases: Handle projects with unusual structures gracefully
License
This project is dual-licensed under either:
- MIT License - see the LICENSE-MIT file for details
- Apache License 2.0 - see the LICENSE-APACHE file for details
You may choose either license at your option.
Acknowledgments
Built with excellent open-source libraries:
- Clap - Command-line argument parsing with derive macros
- Rayon - Data parallelism for fast directory scanning
- Colored - Beautiful colored terminal output
- Indicatif - Progress bars and spinners
- Inquire - Interactive prompts and selection
- WalkDir - Recursive directory iteration
- Humansize - Human-readable file sizes
- Serde + TOML - Configuration file parsing
- dirs - Cross-platform config directory resolution
Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Crates.io: clean-dev-dirs