Duplicates, proven
Byte-identical copies across folders, verified by full hash. Pick the one to keep, and the rest go to the Bin.
A free photo and video organiser for years of accumulated memories. Bring your files together on your own disk, then review today’s date across every year: keep what matters and remove what doesn’t.
Culling simply means choosing what to keep and what to remove.
Free and open source. Runs locally on macOS 14 or newer, with a browser interface. Also available for servers with Docker.
On 30 September, review your photos and videos from 30 September in 2016, 2019, 2023 and every other year in your library.
K keeps X removes F favourites ⌘Z undoes ⇧R marks the date reviewed
The Year calendar shows how much still waits on each date, and which ones you have already reviewed.
Import camera files, iCloud Photos and Google Photos exports.
Files are grouped by the day they were taken, with related files kept together.
Keep, favourite or remove each item, then mark the date reviewed. Years of photos become small daily sessions.
YYYY/YYYY-MM/YYYY-MM-DD, dated from its metadata, then its name, then its file date.Bursts, near-identical shots, screenshots and copies pile up around the moments that matter. Clouds charge every year to store all of it, unsorted, and the backlog only grows.
Clouds are brilliant at keeping every device in step. Keep an independent copy, so access to your memories doesn’t depend on one account. Daddy, Cull! keeps your library as plain folders on a disk you own, ready to back up to a second drive, a NAS or a cloud of your choice.
Photos end up in iCloud, Google Photos and Lightroom at once. Clean one and the others are still full, so the effort never adds up.
Local, and in a layout any app can read. Back the folder up like any other, so a second copy lives somewhere else too.
Nothing is deleted without passing through the Bin, and the Bin checks every file's SHA-256 fingerprint again before it moves it.
Restore removed files before your chosen Bin retention period ends. ⌘Z takes back your last hundred choices.
Only byte-identical copies are called duplicates, checked by full hash, and you choose which copy stays.
With Cull Sync on, a photo you remove can also be removed from Apple Photos and iCloud. Nothing changes until you press Apply, macOS asks you to confirm, and removals go to Recently Deleted.
It listens on 127.0.0.1 only, and only a private writer process changes the library. The web process only reads it.
Fast enough to enjoy, and careful with every file.
Byte-identical copies across folders, verified by full hash. Pick the one to keep, and the rest go to the Bin.
Step through with the arrow keys, turn with ] and [, open Info for the camera and fingerprints. A RAW and its JPEG are one photo, and HDR video is tone mapped.
⌘Z takes back each choice in turn and ⌘U does it again. The Log lists every decision, and a removed file can be restored until its Bin retention period ends.
Removed files wait in the Bin for the days you choose. Emptying and restoring run in the background as tasks you can stop or try again file by file, and they carry on after a restart.
An open page shows files the moment they reach the library. A reviewed date that gains new files comes back with a red dot until they are decided.
Marking a date reviewed keeps your streak going, with a card and a little confetti. The flame opens a calendar of the run.
Drop Takeout exports into a folder. Each photo is checked against the library and sorted, so you add only what is missing, never over anything and never twice.
Cull Sync, a small menu-bar helper, carries what you removed and favourited across to the Photos app. A photo removed there also leaves iCloud, so nothing changes until you press Apply, and removals go to Recently Deleted.
Each page opens with a short guide to how it works, keys drawn as keys. ? lists every shortcut, and every action shows its key in its tooltip.
The sidebar counts the photos and videos in the library and the space each takes, and the Year calendar shows how much still waits on every date.
The theme follows your clock, not a setting: light by day, dark by night, so an evening session never glares. Chrome can install it as an app.
On a Mac it runs as two background services. On a server, Docker Compose runs a web container that can only read the library and a writer that files new arrivals.
The library is plain folders, so Immich, Jellyfin, Plex or Finder can all read it as an external library. Favourites you set in Daddy Cull are set in Immich too, and Jellyfin is asked to scan again a minute after files leave the library, so it stops showing videos that are gone.
Let a coding agent do it. Paste this prompt into Claude Code, Codex, Cursor or any agent that can run commands on your Mac. It reads the installer, asks where your photos should go, installs, and checks that everything runs.
Install Daddy, Cull! on this Mac for me, end to end, and leave it running.
Daddy, Cull! is a free, open-source photo and video organiser that runs locally: https://daddy-cull.turalali.com
Code, installer and README: https://github.com/tural-ali/daddy-cull
Work in Terminal on this Mac as my own user. Never use sudo. Before each step, tell me in one line what you are about to do.
1. Read the installer first: https://raw.githubusercontent.com/tural-ali/daddy-cull/main/install.sh
Tell me in a few lines what it installs and changes. It checks this Mac itself (macOS 14 or newer, 4 GB memory, 2 GB free space, port 8830 free) and changes nothing if a check fails.
2. Ask me, in one message:
- Where my photo library should live. The default is ~/Pictures/Daddy Cull/Library. Downloads, Desktop and Documents don't work, because macOS guards them. An external drive is fine.
- Whether to download my iCloud Photos (installs icloudpd). Optional.
- Whether to copy photos from the Photos app on this Mac (installs osxphotos). Optional.
3. Check for Homebrew: test -x /opt/homebrew/bin/brew || test -x /usr/local/bin/brew
If it is missing, installing it needs my Mac password, which you can't type. Give me the full command from step 4 to paste into Terminal myself, wait until I say it has finished, then go on to step 5.
4. Run the installer with my answers, for example:
curl -fsSL https://raw.githubusercontent.com/tural-ali/daddy-cull/main/install.sh | bash -s -- --yes --library "$HOME/Pictures/Daddy Cull/Library" --with-icloud --without-apple-photos
If port 8830 is taken, put DADDY_CULL_PORT=8860 in front of bash and use that port from here on.
5. Check it works: run daddy-cull status, and check that http://127.0.0.1:8830 answers. If daddy-cull is not found, use /opt/homebrew/bin/daddy-cull or /usr/local/bin/daddy-cull. If anything failed, read the logs in ~/Library/Application Support/Daddy Cull/logs and the Troubleshooting section of the README, fix what you can, and tell me what you changed.
6. Hand over what only I can do, and wait for me:
- If the library is on an external drive: I add ~/Library/Application Support/Daddy Cull/app/current/bin/cull to Full Disk Access in System Settings, Privacy & Security. Then you run daddy-cull restart.
- If I chose iCloud: I run daddy-cull icloud sign-in in my own Terminal. It asks for my Apple ID password and a two-factor code.
7. Finish with daddy-cull open setup, and tell me where my library and Import folders are and how new photos get in.
Rules: never type my passwords, Apple ID or two-factor codes, and never ask me to paste them into this chat. Never move, rename or delete my existing photos. Don't change system settings yourself.
The agent stops for the two things only you can do: your Mac password, if Homebrew needs installing, and your Apple ID sign-in, if you turn on iCloud.
The current release is a beta. The installer checks your Mac, installs what it needs, and opens setup in your browser. Paste this into Terminal:
curl -fsSL https://raw.githubusercontent.com/tural-ali/daddy-cull/main/install.sh | bash
On Linux, Unraid, Synology or TrueNAS, run it with Docker Compose. Fill in examples/.env with the folders, the user that owns them and a private key, then build and start both containers.
git clone https://github.com/tural-ali/daddy-cull.git cd daddy-cull cp examples/.env.example examples/.env VERSION=$(tools/version.sh) docker compose -f examples/docker-compose.yml up -d --build
The server guide covers the layout, Google Photos, Immich, Jellyfin, updates and keeping it off the open internet.
| macOS | 14 Sonoma or newer |
|---|---|
| Processor | Apple silicon or Intel |
| Memory | 4 GB |
| Free space | 2 GB, plus room for your library |
| Account | Your own user, not sudo |
| Beforehand | No tools to install beforehand; the installer sets up the dependencies. Homebrew, if it is missing, asks for your Mac password |
The pages you click through use the same API an addon or a script can. It is versioned and fully documented: 86 routes in 22 groups, each with its parameters, errors and the permission it needs.
curl line for every route and a Send button for those that only read./api/openapi.json, for any tool that reads it.GET /api/events streams what happens as server-sent events, and picks up where it left off after a break.Everything beyond reviewing dates, duplicates and the Bin is an addon you can turn off in one place, with its pages, routes and background work stopping with it.
An addon is a folder with an addon.json. It shows on the Addons page a moment after you drop it in, says what it may do before its key is written, and adds its own pages to the sidebar in a sandboxed frame that is told the theme.
{ "id": "hello-cull", "name": "Hello, Cull", "version": "0.1.0", "summary": "Shows what the library holds.", "pages": [{ "id": "hello", "label": "Hello", "section": "tools", "url": "http://127.0.0.1:8900/" }], "permissions": [] }
Every addon may read. Anything more, review, import, bin, delete or settings, is asked for, shown before it is turned on, and checked on every request.
Built in: Screenshots, Saved from social, Google Photos, Apple Photos, Immich, Jellyfin, Library totals and more.
The latest betas:
The server keeps them in their own table and matches them to files by name and day, the way deletions are handed across. Checked against 779 files already reviewed here, only two of Apple's judgements stood apart from chance, so those are the only marks: a star where Photos would pick the picture for Memories, a cracked frame where it calls the shot failed, each a filter too, with the rest of what Photos found in the viewer's Info. The osxphotos pin moves to 0.77.2.
Hold a photo to select it and tap others to add them, swipe through the review with the next photo sliding in, pull down to go back, push up for Info, and pinch or double-tap to zoom.
As a RAW and its exports are, once both record the same moment, to a fraction of a second, and the same camera, since a name alone is shared by different pictures.
Over one HandBrake encoded again, and over an export whose metadata was rewritten, flagged as such, even where its sidecars name a person, as the Bin now copies a copy's sidecars beside the one kept when that has none, so the tags stay in the archive.
Which stays with the photo, so the three copies of 2021 left beside IMG_3903, IMG_3910 and IMG_2165 can go and Jellyfin stops listing them as films.
The page left fades and lifts as the next is read and cannot be pressed, the next rises into its place, and a date pressed in the Year opens out of its own square, which grows to fill the panel before the day's photographs come in one after another, while going back zooms the year out onto that day.
Then the camera dives through the day tiles and every date flies in from in front of the screen to its place, as a phone's home screen opens.