A fast, open-source, cross-platform photo-culling app for professional
workflows.
Ingest → cull → filter → export → hand off. Speed is the product. 🦩
User guide · Keyboard · Screenshots · Architecture · Build plan · License
A flamingo is nature's culler: a filter feeder that pumps in huge volumes, ejects the water and mud, and keeps only what's worth keeping. That's the job — get through thousands of frames and keep the keepers, fast.
Rating, flagging and colouring a shoot in the grid · more screenshots → · placeholder photos via Lorem Picsum (Unsplash; see credits)
Photography software keeps drifting behind subscriptions and the cloud, while the open-source side stays thin — capable, but rarely polished for a real culling session. I wanted a fast, keyboard-first culling app I owned outright, so I built one for my own photo workflow and shared it. Bug reports and feedback are very welcome — see Bug reports & feedback.
Grab the latest build from the Releases page.
- Linux — download the
.AppImage, make it executable, and run it:chmod +x Cullimingo-x86_64.AppImage ./Cullimingo-x86_64.AppImage
- Linux (Flatpak) — install from Cullimingo's own Flatpak repository
(x86_64 and ARM); it updates through
flatpak updateor your software centre:flatpak install --user https://nielsfranke.github.io/Cullimingo/io.github.nielsfranke.Cullimingo.flatpakref
- macOS — download
Cullimingo-arm64.dmgfor Apple Silicon (M1 and later) orCullimingo-x86_64.dmgfor Intel Macs (macOS 12 or later). Open it and drag Cullimingo to Applications. The app is signed and notarized by Apple.
Both builds are self-contained — no Homebrew or apt libraries needed. See DISTRIBUTION.md for the details.
- Cull at speed — open a folder of RAWs, JPEGs or HEIC/HIF → virtualized, dense dark grid → keyboard rate / flag / colour that persists instantly. Turn on auto-advance (Settings → General) to jump to the next photo after each mark. Multi-select + batch marking, right-click palette (incl. Delete… to the Trash, sidecars and all), tabs for multiple folders.
- Loupe & compare — full-screen loupe (zoom/pan, neighbour prefetch) and a 2-up / n-up compare view, both keyboard-cullable.
- Exposure brackets — auto-detected from EXIF and collapsed to one cell per
bracket in the grid (the reference frame badged with its count). Expand a
selection to every ±EV sibling with
G— so client picks re-attach their brackets before export — plus optional mark-the-whole-bracket, and manual stack / unstack that round-trips via XMP. - Real filtering & selections — quick-filter bar (rating / flag / colour / keyworded / selected, live counts), live filename search, a RAW / JPEG file-type filter, saved named selections, and ⌘F find by a pasted filename list. Import a Picdrop/CSV list to select the matching RAWs.
- Ingest — verified (SHA-256) card import with a token-based rename template, dual-destination (the backup is always read back), throughput readout, and auto card-detect that opens Import on insert. Pick which shooting days to bring in, with or without the JPEGs. Copies land under a hidden part name and are published only once verified, never replacing an existing file; a full disk or an unplugged destination is caught before anything is copied, and a partly unreadable card is reported instead of passing as imported.
- Metadata & interop — XMP sidecars round-trip rating + colour + keywords
with Capture One and Lightroom (read embedded XMP too); pick/reject lives in a
private
cullimingo:namespace. Re-sync adopts external edits, flags conflicts. - Captioning for journalists — a full IPTC Core editor (single photo or
batch), saved metadata templates with named snapshots and apply-on-ingest,
=code=replacements and multi-field "hot codes", IPTC Subject Code / Media Topics, and offline GPS→city reverse geocoding. Exports embed IPTC as both XMP and legacy IIM. - Export — non-modal background export (bounded-concurrency isolate pool): resize / quality / sharpen / rename template / size cap, into one folder or beside each original — keep culling while it runs. RAW exports use the embedded preview.
- Hand-off — drag originals straight to Finder, verified copy / move the selection (with XMP sidecars) to any folder, send it to your own editors (Capture One / Lightroom / Photoshop / GIMP / …) via the right-click menu or ⌘E, wire it straight to an agency over FTP / FTPS / SFTP, or send to / pull client ratings back from a ContactSheet gallery.
- Polish — metadata inspector, burst & duplicate grouping (+ perceptual-hash "find similar"), RAW+JPEG pairing, configurable shortcuts, performance presets, in-app log viewer, reopen-last-folders.
RAW preview extraction is C/C++ FFI via LibRaw (no Rust); thumbnails decode and resize off the UI isolate through libvips. The UI isolate never blocks.
Cullimingo is not a RAW developer, not a forever catalog, and no AI
culling in v1 — see BUILD_PLAN.md for the non-goals. Video
is culled by its poster frame; playback hands off to your system player
(no in-app playback).
| Keys | Action |
|---|---|
| arrows | navigate the grid |
1–5 |
rate · 0 / Delete clears |
P / X |
pick / reject |
6 7 8 9 |
colour: red / yellow / green / blue · Backspace purple |
Space |
select · ⌘/Ctrl-click toggle · Shift-click range |
G |
expand the selection to its exposure bracket |
Enter / F |
loupe · C compare · B burst |
I |
metadata inspector · K keywords |
⌘/Ctrl O T W A F S E R |
open · new tab · close tab · select all · find · export · send to primary editor · refresh |
? |
shortcuts cheat sheet (rebindable in Settings) |
Instantly familiar — the defaults follow the de-facto culling keys
(1–5 rate, 0 clears, P/X pick/reject, 6–9 colours). No new
muscle memory to learn, and every key is rebindable in Settings. For a
pick/reject-through-the-shoot pass, enable Auto-advance to the next photo
after rating or flagging in Settings → General.
Full list: Keyboard on the wiki.
| 📖 User guide | What Cullimingo does and how to cull with it |
| ⌨️ Keyboard | The full keyboard map |
| 🖼️ Screenshots | Grid, loupe, compare and the inspector |
| 🛠️ Development | Set up, run and build from source |
| 🎞️ RAW & interop | LibRaw, libvips, XMP round-trip with C1 / Lightroom |
| ✍️ Captioning & delivery | IPTC templates, hot codes, reverse geocoding, FTP/FTPS/SFTP wire transmission |
| 🏗️ Architecture | Layers, isolates, cache — the technical map |
| 🗺️ Build plan | Phased plan, locked stack and rationale |
flutter pub get
dart run build_runner watch --delete-conflicting-outputs # keep running
flutter run -d macos # or: flutter run -d linuxmacOS needs Xcode + CocoaPods; both platforms need LibRaw and libvips for
RAW/thumbnail decode (brew install libraw vips, or the distro -dev packages).
Full setup and the pre-commit checks are in
Development.
Please open a GitHub issue
for bugs, questions and feature ideas — rather than email. Issues keep the
details, screenshots and follow-ups in one place, other users with the same
problem can find them, and you get notified when a fix ships. A useful bug
report says which Cullimingo version you run (Settings → About), your OS and
Mac model or Linux distro, and — for files that don't display — the camera
model and file type (e.g. Sony .ARW).
Cullimingo is free, open-source, and built in my spare time. If it saves you time on a shoot and you'd like to help keep it going, you can buy me a coffee — every bit is appreciated. ☕
GNU AGPL-3.0-or-later. Cullimingo is free software — use, modify, and self-host it freely. If you distribute a modified version, you must release your changes under the same license and make the corresponding source available.
Contributions are welcome under a simple Contributor License Agreement.
Reverse geocoding uses place data from GeoNames
(CC BY 4.0), bundled as
assets/geo/cities.tsv.gz (regenerate with tool/build_gazetteer.sh).
The Media-Topics autocomplete uses the IPTC Media Topics
NewsCodes (CC BY
4.0, © IPTC), bundled as
assets/iptc/mediatopics.tsv.gz (regenerate with
tool/build_media_topics.sh).