Skip to content
Back

phota

Folder cleanup utility · Python, FastAPI, React · Jun 2026

Every photo folder I touch turns into a mess. Camera dumps next to screenshots next to exports, five near-identical shots of the same thing. phota is the cleanup tool I wanted: type phota in a terminal and a small control window opens on the folder I already have open in Finder. No importing, no library. The folder stays a folder.

The phota picker window listing the folders currently open in Finder
Type phota in any terminal. It offers the folders you have open in Finder.

Photo apps want to own my photos. Import them, organize a copy inside a database, and the original folder is still a mess. I wanted the opposite: a tool that walks into the folder, tidies it in place, and leaves. Re-ordering is written back as numbered filenames, so the order survives anywhere. Repeats are found with a perceptual hash and only flagged, nothing moves until I say so. Anything that touches disk writes an undo manifest first.

📁 photos
IMG_2210.HEIC
DSCF2140.JPG
DSC_0001.jpg
DSCF2138.JPG
DSCF2142.JPG
IMG_4824.JPG
DSC_0002.jpg
IMG_2968.HEIC
DSC_0044.jpg
IMG_4958.HEIC
IMG_4826.JPG
P1010099.RW2
IMG_4825.JPG
IMG_2211.HEIC
Macintosh HD › Users › kj › Documents › photos14 items · 0 sets of repeats
photacontrolling: photos
Organizeon-device · no key needed
Your folder, mid-mess. Drive it with phota below.

phota works on the folder you already have open. Drive a row, watch your folder reorganize in place. Undo anytime; nothing leaves the folder.

A Python engine scans the folder once into a local SQLite index: EXIF, sharpness, exposure, perceptual hashes, burst groups. A FastAPI server wraps the engine and serves a small React app on localhost, so the window is just a browser doing its best impression of a utility.

Bring your own key (Claude, GPT, or a local model) and an optional AI layer appears: semantic search, and picking the best shot of a burst. It stays hidden until you add one, and everything else works without it.

Python, FastAPI, and SQLite for the engine. React, Vite, and Tailwind for the window. Built with Claude Code, spec first: the rule that nothing touches originals without an explicit apply came before any feature, and 190 tests hold it in place.

View the code on GitHub ↗