Index · browse · organize your local photos & video.
A fast, local image & video browser and organizer for Windows — an indexer and library for the folders you already have. It replaces File Explorer for the "just let me look at my photos" case: no multi-second waits on big, image-heavy folders like a Dropbox Camera Uploads or a Screenshots dump.
Built by Funcular Labs as a real-world showcase for FunkyORM, our .NET micro-ORM — Aperture's SQLite data access runs on it.
Aperture keeps a persistent local index + thumbnail cache, so the first scan of a folder is the only slow one; every open after that paints instantly. Everything stays on your machine — it never uploads anything or phones home.
- Union across folders. Add folders from anywhere on disk and browse them as one date-sorted view; aliases, and a show/hide checkbox on every folder and subfolder.
- Separate libraries. Keep a Work and a Personal library (or more) that never see each other's folders, tags, or search results. They're listed under LIBRARIES in the folder pane: click one to switch to it. Each library has its own index, thumbnail cache, and settings.
- One window. Starting Aperture while it's already open brings the open window to the front (restored if it was minimized) instead of opening a second one.
- Instant, virtualized grid with five zoom levels (
Ctrl+wheel /Ctrl+±) and square, center-cropped tiles. - Collapsible date sections that auto-collapse older buckets, so you land on ~2 screenfuls instead of scrolling forever; grouped by day, week, month or year to suit both the photos and the window's width.
- Tags & notes per file — stored locally, keyed by path, and kept across re-indexing. Multi-select tagging; a tag manager; import/export as portable JSON to move annotations between machines.
- Gmail-style search:
tag:beach,note:trip,is:video/is:image,type:mp4,has:tag,camera:,folder:, quoted values (tag:"date night"), bare words match everywhere — all AND-ed, withtag:clauses OR-ed together. - Quick view (
Space/Enter/ double-click) — a full-screen quick-look with←/→paging and zoom (Ctrl+wheel at the pointer,Ctrl+±,Ctrl+0to fit; drag to look around a zoomed photo); right-click for the full item menu. - Inspector pane (dockable right or bottom) — large preview with zoom/pan, the item's tags & notes, and full EXIF/metadata.
- Video thumbnails via the Windows shell; open anything in its default app.
- Keyboard-first, mouse-friendly. Explorer-style arrow navigation, no modal dialogs on the hot paths. Window size/position/monitor and the folder-pane width are remembered.
The repo ships a small sample library so you can try it without pointing it at your own photos:
- Build & run (below).
- Click ➕ Add Folder and choose this repo's
sample/folder (or any subfolder).
Requires the .NET 10 SDK.
dotnet build
dotnet run --project src/Aperture.App
dotnet testBuild a distributable single-file exe (needs the .NET 10 Desktop Runtime on the target):
pwsh ./publish.ps1 # framework-dependent (small)
pwsh ./publish.ps1 -SelfContained # bundles the runtime (portable, larger)→ publish/Aperture.exe
Everything is local. Each library keeps its index, thumbnail cache, and settings in a folder
of its own (aperture.db, thumbs.db, settings.json, plus a small aperture.lock that tells
any other copy of Aperture — on this PC or another, for a library on a shared drive — that the
library is open):
- Your first library, Default, lives in
%LOCALAPPDATA%\Aperture. - New library… (the + beside LIBRARIES) asks for a name and a folder of photos and
videos to put in it, and keeps the new library's own files in
%LOCALAPPDATA%\Aperture Libraries\<name>(or<name> (2), and so on, if that folder is taken). Open library… adds a library that already exists, wherever it is. - The list of your libraries is
%LOCALAPPDATA%\Aperture Libraries\catalogs.json.
Delete library files (right-click a library you aren't in) deletes only Aperture's own files
for it — the index, thumbnail cache, and settings, which hold that library's tags and notes.
It never deletes your photos or anything else in that folder. To reset Aperture completely,
close it and delete %LOCALAPPDATA%\Aperture, %LOCALAPPDATA%\Aperture Libraries, and the
folders of any libraries you added from elsewhere.
Set the APERTURE_DATA_DIR environment variable to run against one data folder instead (handy
for testing): Aperture then uses only that folder, ignores the library list, and shows no
libraries in the folder pane.
Upgrading from the older "Reel" build? On first launch Aperture moves an existing
%LOCALAPPDATA%\Reelstore into the new location automatically — your index and tags carry across, once.
Aperture.Core— indexer,FileSystemWatcher, thumbnail pipeline, SQLite storage, search/sort/caption engine, models. No WPF references; unit-tested in isolation.Aperture.App— WPF UI with a small hand-rolled MVVM, grid virtualization, hotkeys, and dialogs.Aperture.Core.Tests— xUnit tests over indexing, thumbnails, orientation, the watcher, union queries, formatting, search, tags, multi-item merges, tag recency, the import/export round-trip, and the data migration.
Thumbnails decode with SkiaSharp (JPEG/PNG/HEIC/WEBP) with a Windows shell fallback for exotic formats and video frames. EXIF via MetadataExtractor.
Storage is SQLite, with the roots/items data access running on
FunkyORM (Funcular Labs' own micro-ORM) —
the grid's union query is resolved via FunkyORM's [RemoteProperty] join attributes rather than
hand-written SQL. Schema DDL and the thumbnail BLOB store use raw Microsoft.Data.Sqlite (metadata
and thumbnail BLOBs live in two files so BLOBs don't bloat the metadata page cache).
sample/ is a small, redistributable demo library — free-license photographs
from Lorem Picsum (Unsplash License) plus original synthetic
images and a short video. Nothing there is anyone's personal photo. See
sample/NOTICE.md; regenerate with
scripts/make-sample.sh.
Daily-driver quality on Windows, backed by 87 Core unit tests. Built as a series of milestones (indexer/cache → union grid → sections/sort/captions → daily-driver polish) plus many rounds of usage feedback; see the commit history for the full trail.
Code is MIT. The bundled sample photographs are under the Unsplash License
(see sample/NOTICE.md); the synthetic sample images/video are original.

