Skip to content

Latest commit

 

History

66 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FolderLens

FolderLens

A fast, modern folder size analyzer for Windows. See what's eating your disk — as a tree, a treemap, a top-files list, a file-type breakdown, or duplicate copies.

CI Release

Download

Grab the latest build from the Releases page:

  • FolderLens.exe — standalone, no Python required. Just run it.
  • FolderLens-<version>-win64.zip — folder build; use this if your antivirus flags the single exe (see Antivirus notes).
  • FolderLens_Setup_<version>.exe — versioned installer with Start Menu and optional Explorer context-menu integration.

Features

Opens on a start screen offering Home, Desktop, Downloads, Documents, Pictures, Videos, Music and your drives — pick one and it scans, no file dialog required.

FolderLens scans a whole directory tree once — with a shared work queue and a bounded worker pool that keeps one large folder parallel, avoids creating one task per subtree, and automatically uses gentler metadata concurrency for UNC and mapped network drives. The complete in-memory tree can then be explored six different ways with zero rescanning:

  • 🧭 Explore — keep the folder hierarchy, treemap, and selection details visible together. Selecting a row or map tile follows the same item on the other side; zooming the map keeps the tree open.
  • 🌳 Tree view — expandable folder tree with a usage bar, size, item count, type, and date at every level. Expanding a folder is instant.
  • 🗺️ Treemap — a hierarchy-first cushion-shaded map where every rectangle's area is its size, folders get a reserved header band, labels are capped to the useful large tiles, and dense tails are grouped into a single “smaller items” tile. Image files are painted with their own thumbnail so you can recognise them at a glance. Hover for a peek preview of the picture, click a folder to zoom in, right-click to go back.
  • 🏆 Largest files — the top 100 biggest files anywhere in the tree, with their locations and small inline previews.
  • 🧩 File types — size and count broken down by category (video, image, code, …) with proportional bars.
  • 🎛️ Type and advanced filters — apply categories, extensions, filename terms, size and modified-date ranges, and hidden-file rules across every view. Matching folders remain as context, and Windows hidden attributes are respected.
  • 👯 Duplicates — finds byte-identical copies and shows exactly how much space keeping one of each would free. Narrowed by size, then a head/tail sample, then a full hash, so almost nothing is read twice.
  • ⭐ Filter presets — one-click presets such as Images only, Large videos, and Not modified for a year, plus your own saved filters.
  • 🕰️ File age — the File Types view also groups the same files by last-modified age.
  • 💾 On-disk size (opt-in) — for local drives, measure allocated and unique on-disk bytes and hardlinks next to the logical size. Unknown values stay “unknown”; nothing is estimated.
  • ⏭️ Skip a stuck folder — when a network folder stops responding, skip it and let the scan finish; the result is clearly marked partial.

Image viewer & annotation

Double-click any image (in any view) to open it:

  • ◀ ▶ step through every image in the folder, with a position counter
  • ⬅ Up and a subfolder picker to move around without leaving the viewer
  • ✏️ Annotate in two modes:
    • Basic — pen, marker, arrow, eraser
    • Advanced — adds line, rectangle, ellipse, text, and redo
  • colour palette, brush size, undo/redo, clear, and Save as… to export the annotated copy at full resolution

Annotations are stored relative to the image, so they stay put when you resize or zoom, and export sharp at the original resolution.

Plus:

  • 🧭 Clickable breadcrumbs — jump straight to any folder in the path
  • 🎨 Colour legend under the treemap, so the colours actually mean something
  • ⌨️ Keyboard treemap navigation — arrow keys move through tiles, Enter opens the focused item, and Backspace goes up. In Explore, the focused item also selects its row in the folder tree.
  • ⌨️ Shortcut help built in (F1), and hover hints on every icon button
  • 🔎 Instant search across the whole tree (Ctrl+F)
  • 🧵 Fully responsive — scanning, zipping, deleting, and exporting all run off the UI thread, with live progress and a Stop button
  • 🗑️ Manage — multi-select to zip, delete, or open in Explorer (right-click, toolbar, or Delete key); sizes update without rescanning
  • 📤 Export the current visible results or full scan as a scoped CSV or JSON report, or the treemap as a PNG
  • ♻️ Recycle Bin — deletions are undoable by default (permanent delete is a setting)
  • 💽 Disk usage shown in the status bar (free / total)
  • 🌗 Light / dark theme, remembered between sessions, along with your last folder and view
  • ⬆️ Auto-update from GitHub releases
  • 🖱️ Explorer context menu integration
  • 🛡️ Handles "access denied" gracefully and flags how many items it couldn't read

Usage

# open the app
python main.py

# analyze a specific folder
python main.py "C:\Users\Documents"

# console mode (no gui)
python main.py --console "C:\Users\Documents"

# Explorer context menu (run as admin)
python main.py --install
python main.py --uninstall

# print version
python main.py --version

# headless reports: same scanner, filters, and export format as the app
python main.py "D:\Photos" --category image --json photos.json
python main.py "D:\Work" --ext .log --modified-before 2025-01-01 --csv old-logs.csv
python main.py "C:\Data" --on-disk --console

Report mode never deletes, moves, or zips anything. It exits with 0 for a complete scan, 2 when some folders could not be read (partial totals), and 1 on failure. Any filter option (--category, --ext, --name, --min-mib, --max-mib, --modified-after, --modified-before, --exclude-hidden, --on-disk) runs headless.

Keyboard shortcuts

Key Action
F5 Rescan current folder
Ctrl+F Focus search
Esc Clear search
Delete Delete selected (tree / largest files / duplicates)
F1 Keyboard shortcut help
Ctrl+O Browse for a folder
Backspace Go to the parent folder
Double-click Open folder / open image viewer

In the image viewer:

Key Action
← → Previous / next image
Ctrl+Z / Ctrl+Y Undo / redo annotation
Esc Close

In the Treemap, Tab to the map, use the arrow keys to focus a tile, press Enter to zoom into a folder or open an image, press Backspace to move up, and press Shift+Backspace to move forward in the zoom history. The Tree view provides the full hierarchy as a keyboard accessible table.

Requirements

  • Windows 10/11
  • Python 3.9+ (only when running from source)

Antivirus false positives

PyInstaller executables are commonly false-flagged by antivirus engines. The build is tuned to minimize this (no UPX, embedded metadata, manifest, icon, and a folder-build alternative). If your machine still quarantines the download, see docs/ANTIVIRUS.md — the short version is: use the .zip folder build, and/or report the false positive to Microsoft (they delist confirmed ones quickly).

Development

pip install -r requirements.txt pytest

# run the test suite
python -m pytest tests -v

# build both executables locally (Windows)
build.bat

# build the versioned installer (Windows, Inno Setup 6 required)
python installer/build_installer.py

Scan baseline for 4.0 development

Create each corpus once. The generator writes deterministic, nested .bin files and refuses to populate a nonempty directory:

python benchmarks/create_dataset.py C:/test-data/files-10k --files 10000
python benchmarks/create_dataset.py C:/test-data/files-100k --files 100000
python benchmarks/create_dataset.py C:/test-data/files-1m --files 1000000

For a share run, copy the corpus to the share first and scan that unchanged copy. Run the same harness against the same unchanged folder or share for each version, and keep the report files outside the scanned folder:

$harness = 'C:/work/FolderLens/benchmarks/scan_baseline.py'
$env:FOLDERLENS_SCANNER_SOURCE = 'C:/work/FolderLens-v3.4.0'
python $harness C:/test-data/million-files --runs 5 --version-label v3.4.0 `
  --dataset-label local-1m --storage-label NVMe-SSD --cache-state warm `
  --defender enabled --output C:/bench/3.4.0.json
Remove-Item Env:FOLDERLENS_SCANNER_SOURCE
python $harness C:/test-data/million-files --runs 5 --version-label 4.0-candidate `
  --dataset-label local-1m --storage-label NVMe-SSD --cache-state warm `
  --defender enabled --output C:/bench/candidate.json
python C:/work/FolderLens/benchmarks/compare_scans.py C:/bench/3.4.0.json `
  C:/bench/candidate.json --output C:/bench/comparison.json

For the shipped v3.4.0 baseline, point FOLDERLENS_SCANNER_SOURCE at a clean v3.4.0 checkout. The current harness adapts to its older scanner callback API; --version-label records the tag while application_version preserves the version embedded in that source. Use matching dataset labels, cache state, Defender state, host, and path. The report includes first progress, time to the first visible file sample, first 500 entries, first partial result, scan duration, process RSS, Python allocation peak, queue high-water marks, item count, and inaccessible paths. During a scan the app shows a provisional list of up to 25 largest files seen so far; it is clearly labeled until the final ranking is available. For SMB runs, pass the measured --network-rtt-ms and --network-bandwidth-mbps. Timeout runs cancel and are marked incomplete. The comparison reports ratios and checks whether both versions scanned the same item and inaccessible counts; it does not treat a single run as a release verdict.

Snapshot bytes are observed values until the scan finishes; inaccessible paths keep a completed result partial. Logical size counts each hardlink path separately. Reparse points and symlinks are listed but never traversed by default. This harness measures scanning; record SMB RTT/bandwidth and UI input latency separately, and repeat both warm-cache and cold-cache runs.

Project structure

FolderLens/
├── main.py               # entry point and command-line options
├── cli.py                # headless JSON/CSV reports and exit codes
├── query.py              # shared QuerySpec projection engine and filter presets
├── app.py                # UI (customtkinter + ttk): views, image viewer, toolbars
├── scanner.py            # single-pass parallel tree scanner
├── analysis.py           # query projections, treemap layout, largest-files, CSV
├── file_actions.py       # stale-scan validation and safe ZIP/delete operations
├── duplicates.py         # size -> sample -> full hash duplicate detection (pure, tested)
├── locations.py          # start-screen places and path breadcrumbs (pure, tested)
├── trash.py              # Recycle Bin / XDG trash, with a permanent-delete fallback
├── treemap_render.py     # cushion shading, thumbnails, labels, hit-testing
├── thumbnails.py         # background thumbnail decoding + LRU cache
├── annotate.py           # annotation model, tools, undo/redo, export (pure, tested)
├── imagenav.py           # image/folder navigation for the viewer (pure, tested)
├── file_utils.py         # file type detection, formatting
├── updater.py            # auto-update handler
├── version.py            # version info
├── registry_installer.py # Windows Explorer context menu
├── release_manifest.py   # SHA-256 manifest for release assets
├── benchmarks/           # dataset generator, scan harness, report comparison
├── FolderLens.spec       # antivirus-friendly PyInstaller build
├── app.manifest          # asInvoker + DPI + supported-OS manifest
├── make_version_info.py  # generates the embedded Windows version resource
├── installer/            # versioned Inno Setup installer and build script
├── assets/               # app icon (+ generator)
├── tests/                # pytest suite
├── docs/                 # antivirus notes and the 4.0 acceptance checklist
├── CHANGELOG.md          # release notes
└── .github/workflows/    # CI (tests) + Release (exe, folder zip, installer)

Releasing

Push a tag like v4.0.0 (or run the Release workflow with a tag input). It runs the tests, generates the version resource, builds the AV-friendly one-file exe, one-directory zip, and versioned installer on Windows, smoke-tests the executable and installer install/uninstall flow, and publishes a GitHub release with all three assets and their SHA-256 manifest. The in-app updater uses the one-file exe or folder zip; installer builds are for fresh installs.

License

MIT

About

a lightweight folder size analyzer for windows with explorer context menu integration.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages