TL;DR: shatter is a cross-platform CLI tool that finds and obliterates build caches (node_modules, .next, __pycache__, .gradle, …) across all your projects with a single command. Think npkill but for every ecosystem.
The Problem
If you're like me, you have dozens of repos sitting on disk — course projects, side projects, experiments. Each one hoards node_modules, .next build caches, Python virtual environments, and more. Manually hunting them down is tedious. shatter automates the whole thing.
What Is Shatter?
Shatter is a Python CLI tool that:
- Scans any directory tree for known build artifacts and dependency folders
- Supports 10+ ecosystems — JavaScript, Python, Rust, Go, PHP, Ruby, Java, .NET, Dart, Expo
- Computes sizes in parallel using threaded I/O for fast results
-
Deletes safely with dry-run mode,
.shatterignoreprotection, and confirmation prompts -
Works in CI/CD with
--yesfor non-interactive cleanup
Comparison (How it differs from alternatives)
There are existing tools in this space, but Shatter was built to solve their specific friction points:
Vs. npkill: npkillis fantastic but strictly interactive—you must manually navigate its UI to delete folders. Shatter can be run headlessly via flags, allowing for total automation.
Vs. kondo: kondo(written in Rust) takes a blunt approach; if it detects a project, it wipes all artifacts. Shatter allows for surgical precision—you can wipe your gigabytes of build caches while keeping your local dependencies intact for offline work.
The Safety Net: Neither of the major alternatives has persistent, per-project protection. Shatter’s .shatterignore file acts just like .gitignore, ensuring you never accidentally wipe a legacy project that takes 45 minutes to re-compile.
Real-World Demo: My tabaani Repos
I have two course project repos on my machine:
-
tabaani_cours_v2— a Next.js project -
tabaani-course— contains atravel-agencysub-project
Let's see what shatter finds.
1. Full Scan — tabaani_cours_v2
shatter shatter "C:\Users\everp\Documents\GitHub\tabaani_cours_v2" --all --dry-run
_____ __ __ __
/ ___// /_ ____ _/ /_/ /____ _____
\__ \/ __ \/ __ `/ __/ __/ _ \/ ___/
___/ / / / / /_/ / /_/ /_/ __/ /
/____/_/ /_/\__,_/\__/\__/\___/_/ v0.1.3
Scan Results
╭──────┬──────────────────────────────────────────────┬────────────┬──────────────╮
│ # │ Directory │ Type │ Size │
├──────┼──────────────────────────────────────────────┼────────────┼──────────────┤
│ 1 │ tabaani_cours_v2\node_modules │ deps │ 884.6 MB │
├──────┼──────────────────────────────────────────────┼────────────┼──────────────┤
│ 2 │ tabaani_cours_v2\.next │ cache │ 269.9 MB │
╰──────┴──────────────────────────────────────────────┴────────────┴──────────────╯
╭──────────────────────────── Summary ─────────────────────────────╮
│ │
│ 🗑 Caches: 269.9 MB │
│ 📦 Deps: 884.6 MB │
│ │
│ 💎 Total: 1.1 GB │
│ │
│ ↑ Nothing was deleted (dry run) │
│ │
╰──────────────────────────────────────────────────────────────────╯
1.1 GB of reclaimable space in a single project. The node_modules alone is 884 MB.
2. Full Scan — tabaani-course
shatter shatter "C:\Users\everp\Documents\GitHub\tabaani-course" --all --dry-run
_____ __ __ __
/ ___// /_ ____ _/ /_/ /____ _____
\__ \/ __ \/ __ `/ __/ __/ _ \/ ___/
___/ / / / / /_/ / /_/ /_/ __/ /
/____/_/ /_/\__,_/\__/\__/\___/_/ v0.1.3
Scan Results
╭──────┬──────────────────────────────────────────────────────┬────────────┬──────────────╮
│ # │ Directory │ Type │ Size │
├──────┼──────────────────────────────────────────────────────┼────────────┼──────────────┤
│ 1 │ tabaani-course\travel-agency\node_modules │ deps │ 420.0 MB │
╰──────┴──────────────────────────────────────────────────────┴────────────┴──────────────╯
╭──────────────────────────── Summary ─────────────────────────────╮
│ │
│ 📦 Deps: 420.0 MB │
│ │
│ 💎 Total: 420.0 MB │
│ │
│ ↑ Nothing was deleted (dry run) │
│ │
╰──────────────────────────────────────────────────────────────────╯
Another 420 MB from a nested node_modules inside a sub-project.
Combined total across both repos: ~1.5 GB — and these are just two projects!
3. Targeted Scans — Deps Only
You can isolate the scan to just dependencies:
shatter shatter "C:\Users\everp\Documents\GitHub\tabaani_cours_v2" --deps --dry-run
Scan Results
╭──────┬──────────────────────────────────────────────┬────────────┬──────────────╮
│ # │ Directory │ Type │ Size │
├──────┼──────────────────────────────────────────────┼────────────┼──────────────┤
│ 1 │ tabaani_cours_v2\node_modules │ deps │ 884.6 MB │
╰──────┴──────────────────────────────────────────────┴────────────┴──────────────╯
╭──────────────────────────── Summary ─────────────────────────────╮
│ 📦 Deps: 884.6 MB │
│ 💎 Total: 884.6 MB │
│ ↑ Nothing was deleted (dry run) │
╰──────────────────────────────────────────────────────────────────╯
4. Fast Mode — Skip Size Calculation
When you don't care about exact sizes and just want to see what's there:
shatter shatter "C:\Users\everp\Documents\GitHub\tabaani_cours_v2" --all --dry-run --fast
Scan Results
╭──────┬──────────────────────────────────────────────┬────────────┬──────────────╮
│ # │ Directory │ Type │ Count │
├──────┼──────────────────────────────────────────────┼────────────┼──────────────┤
│ 1 │ tabaani_cours_v2\.next │ cache │ — │
├──────┼──────────────────────────────────────────────┼────────────┼──────────────┤
│ 2 │ tabaani_cours_v2\node_modules │ deps │ — │
╰──────┴──────────────────────────────────────────────┴────────────┴──────────────╯
╭──────────────────────────── Summary ─────────────────────────────╮
│ 🗑 Caches: 1 dir(s) │
│ 📦 Deps: 1 dir(s) │
│ 💎 Total: 2 directories (run without --fast to see sizes) │
│ ↑ Nothing was deleted (dry run) │
╰──────────────────────────────────────────────────────────────────╯
Instant results — no waiting for size computation.
5. Directory Protection with .shatterignore
Sometimes you want to protect a directory from being scanned (e.g. a project you're actively working on). Just drop an empty .shatterignore file in it:
# Protect the travel-agency sub-project
touch tabaani-course/travel-agency/.shatterignore
# Re-run the scan
shatter shatter "C:\Users\everp\Documents\GitHub\tabaani-course" --all --dry-run
_____ __ __ __
/ ___// /_ ____ _/ /_/ /____ _____
\__ \/ __ \/ __ `/ __/ __/ _ \/ ___/
___/ / / / / /_/ / /_/ /_/ __/ /
/____/_/ /_/\__,_/\__/\__/\___/_/ v0.1.3
⏭ Skipped travel-agency (found .shatterignore)
╭──────────────────────────────────────────────────────────────────╮
│ │
│ ✨ Nothing to clean — your project tree is spotless! │
│ │
╰──────────────────────────────────────────────────────────────────╯
The 420 MB node_modules inside travel-agency is now completely invisible to shatter. Remove the .shatterignore file when you're ready to clean it up.
6. Verbose Mode — Group by Project
shatter shatter "C:\Users\everp\Documents\GitHub\tabaani_cours_v2" --all --dry-run --verbose
Scan Results — by Project
╭──────────────────────────────────────────────┬────────────┬──────────────╮
│ Project / Directory │ Type │ Size │
├──────────────────────────────────────────────┼────────────┼──────────────┤
│ 📁 (no project) │ │ 1.1 GB │
├──────────────────────────────────────────────┼────────────┼──────────────┤
│ └─ node_modules │ deps │ 884.6 MB │
├──────────────────────────────────────────────┼────────────┼──────────────┤
│ └─ .next │ cache │ 269.9 MB │
╰──────────────────────────────────────────────┴────────────┴──────────────╯
╭──────────────────────────── Summary ─────────────────────────────╮
│ 🗑 Caches: 269.9 MB │
│ 📦 Deps: 884.6 MB │
│ 💎 Total: 1.1 GB │
│ ↑ Nothing was deleted (dry run) │
╰──────────────────────────────────────────────────────────────────╯
Key Features Recap
| Feature | What it does |
|---|---|
--dry-run / -n
|
Preview what would be deleted — nothing touches disk |
--deps / -d
|
Target only dependency folders (node_modules, .venv, target, …) |
--cache / -c
|
Target only build caches (.next, __pycache__, .gradle, …) |
--all / -a
|
Target everything |
--fast / -f
|
Skip size computation for instant results |
--verbose / -v
|
Group results by project root |
--yes / -y
|
Skip confirmation for CI/CD automation |
--older-than / -o
|
Only target dirs older than a period (e.g. 30d, 3m, 1y) |
.shatterignore |
Drop in any directory to protect it from scanning |
Install
git clone https://github.com/TheLime1/shatter.git
cd shatter
pip install -e .
Requires Python 3.10+.
Built by TheLime1. Give it a star if it saved you some disk space!
Shatter repo
Top comments (0)