Keep the moments. Clean the rest.

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.

Review today’s date across every year.

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

Every date you finish fills in your year

The Year calendar shows how much still waits on each date, and which ones you have already reviewed.

Your archive 0 of 366 dates reviewed
Fewer than 30 30 to 100 More than 100 Reviewed Today

How it works

  1. Bring your memories together

    Import camera files, iCloud Photos and Google Photos exports.

  2. Let Daddy, Cull! organise them

    Files are grouped by the day they were taken, with related files kept together.

  3. Review a little each day

    Keep, favourite or remove each item, then mark the date reviewed. Years of photos become small daily sessions.

Setup details
  • Copy a camera card or phone export into the Import folder. New files are filed within a minute.
  • iCloud Photos can come in two ways: downloaded every six hours with icloudpd, or copied from the Photos app on this Mac with osxphotos. Google Takeout exports are checked against the library, so only what is missing is added.
  • Each file lands in YYYY/YYYY-MM/YYYY-MM-DD, dated from its metadata, then its name, then its file date.
  • Live Photos, RAW and JPEG pairs and sidecars stay together. Nothing is overwritten, and a file the library already holds is set aside for you to check.

Why it exists

Too much to look through

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.

Keep a copy you control

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.

Too many places to clean

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.

Read how it started

Your files stay yours

Plain folders, on your disk

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 overwritten

Nothing is deleted without passing through the Bin, and the Bin checks every file's SHA-256 fingerprint again before it moves it.

Removed files come back

Restore removed files before your chosen Bin retention period ends. ⌘Z takes back your last hundred choices.

Duplicates, proven

Only byte-identical copies are called duplicates, checked by full hash, and you choose which copy stays.

Apple Photos waits for you

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.

For the person at this Mac

It listens on 127.0.0.1 only, and only a private writer process changes the library. The web process only reads it.

Everything in it

Fast enough to enjoy, and careful with every file.

Duplicates, proven

Byte-identical copies across folders, verified by full hash. Pick the one to keep, and the rest go to the Bin.

A viewer like Google Photos

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.

Undo, a hundred deep

⌘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.

A Bin with a grace period

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.

New arrivals, flagged

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.

A streak worth keeping

Marking a date reviewed keeps your streak going, with a card and a little confetti. The flame opens a calendar of the run.

Google Photos, from Takeout

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.

Apple Photos in step

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.

Guides on every page

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.

Know what you hold

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.

Day and night

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 or a NAS

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.

Plays well with the rest

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.

Install the beta

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.

Requirements on a Mac
macOS14 Sonoma or newer
ProcessorApple silicon or Intel
Memory4 GB
Free space2 GB, plus room for your library
AccountYour own user, not sudo
BeforehandNo tools to install beforehand; the installer sets up the dependencies. Homebrew, if it is missing, asks for your Mac password

Everything is an API

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.

  • A Developers page inside Cull reads the reference, with a curl line for every route and a Send button for those that only read.
  • The whole API is described as OpenAPI 3.1 at /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.
  • Every failure is a status and a sentence you can show as it is.

Addons, including your own

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.

Build one in any language

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.

What's new

The latest betas:

  1. 0.97

    A day page can now show what Apple Photos thinks of each picture. daddy-cull apple-photos scores reads Apple's scores, faces, labels and captions from the Photos library with osxphotos and sends them across with Cull Sync's key

    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.

  2. 0.96

    On an iPad held sideways, Cull answers a finger the way Photos does

    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.

  3. 0.95
  4. 0.94
  5. 0.93
  6. 0.92

    A HEIC and a JPEG of one shot, side by side under one name, are one photo with the HEIC in front

    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.

  7. 0.91

    Keep chooses the camera's own file over every other copy of its footage

    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.

  8. 0.90

    The Bin takes a Live Photo video beside its photo by itself when it is a second copy, identical to the one filed at the same place in .live-photos

    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.

  9. 0.89

    Moving between pages is a motion rather than a fresh load

    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.

  10. 0.88

    The app's own address opens on the Year calendar with the logo alone in the middle, light passing over it

    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.

Every release on GitHub