Fast, local-first photo triage. Plug in an SD card, get an instant grid, cull with the keyboard, and organize the best shots — without the slowness of Lightroom or a dead app like Picasa.
Two principles drive the design:
1–5, 0 clears) with
auto-advance, arrow-key grid navigation, a loupe (detail view) with
prefetch for instant back/forth.C to manually override which photo is the cover.v2 is stable and in active use, built on Svelte 5 (runes) with an
up-to-date dependency stack. The current version is in
package.json, and what changed in it is in
CHANGELOG.md — those are the two files that cannot go stale.
Shipped so far: folder scanning, thumbnail generation with an on-disk cache,
star ratings, the loupe, the justified + virtualized grid, burst-stack detection
with manual cover override, auto-album clustering with move/copy into dated
folders, feed filtering and grouping, a D3 timeline scrubber, tree + fisheye
sidebars, missing-files review, a persisted folder library with offline
browsing, video playback and conversion, GPS place names, on-device image
embeddings and near-duplicate detection, face detection with a browsable People
view and a Face Map, a diagnostic trace log, and Electron packaging with a
native folder picker. See docs/ROADMAP.md for the full
status and backlog (tracked in
GitHub Issues).
The two previous generations of the app are archived under
legacy/ for reference — do not run them (they contain
known insecure patterns, including the Electron anti-patterns this rewrite
deliberately avoids). They exist to port the album-clustering algorithm into
v2.
Requires Node.js >= 22.
npm install
npm run dev
This starts the Express API on http://localhost:4321 and the Vite UI on http://localhost:5173. Open the UI, paste in (or type) a folder path, and scan.
npm run electron:dev
Opens the same app in a real Electron window, with a native "Choose Folder…" button (native OS dialog) instead of typing a path.
To build an installable package for your platform:
npm run electron:build:mac # local smoke-test build (macOS) → release/
npm run electron:build # mac + win + linux (needs Wine for Windows, when run from macOS)
Builds land in release/ (e.g. AutoGallery-<version>.dmg).
AutoGallery is not signed with a paid Apple Developer ID or Windows
code-signing certificate (Apple notarization / Windows signing aren't set up —
see
docs/superpowers/specs/2026-07-06-electron-packaging-design.md).
Each OS therefore warns you the first time you open it. These are one-time steps
per download — here's how to run it anyway on each platform.
macOS (.dmg / .zip) — the app is only ad-hoc signed
(codesign --sign -, which is required so the kernel doesn't kill it on Apple
Silicon, but can't vouch for who built it):
AutoGallery.app → Open → Open in
the dialog. First launch only; after that it opens normally by double-click.xattr -cr /Applications/AutoGallery.app
(-c clears extended attributes, -r recurses into the bundle; the
com.apple.quarantine flag is what triggers the block.)Windows (.exe, NSIS installer) — unsigned, so Microsoft SmartScreen steps
in:
Linux (.AppImage) — no signing concept; just make it executable:
chmod +x AutoGallery-<version>.AppImage
./AutoGallery-<version>.AppImage
If it complains about FUSE, either install libfuse2 or run it with
./AutoGallery-<version>.AppImage --appimage-extract-and-run.
npm test # run the test suite (vitest)
npm run build # build the UI to dist/ (served by Express in production)
npm run format # prettier
| Key | Action |
|---|---|
← → ↑ ↓ | Move selection in the grid |
Home / End | Jump to first / last photo |
Enter / Space | Open the loupe (or expand/collapse a burst stack) |
Esc | Close the loupe / collapse the expanded stack |
1–5 | Rate the selected photo (auto-advances) |
0 | Clear the rating |
C | Set/unset the current photo as its burst stack's cover |
+ / - | Zoom the grid density |
ProcessingService interface (server/processing/), so the engine can be
swapped (native → WASM → Python ML sidecar) without touching the
scanner, index, or UI. server/albums/ is a pure, framework-free module
for time-gap-based album clustering.electron/main.js (ES modules) wraps the
same Express server unmodified; electron/preload.cjs stays CommonJS
(Electron's sandboxed preload loader can't run ESM — verified directly).
Security: contextIsolation, no nodeIntegration, sandboxed, exposing
exactly one contextBridge method for the native folder picker.~/.autogallery/ on your internal disk — a rebuildable cache/index, never
the source photo folders. Ratings, cover choices, the metadata cache, the
thumbnail cache, and the scanned-folders library are all stored there.See CLAUDE.md for the full set of conventions and
invariants, and
docs/superpowers/specs/2026-07-06-photo-triage-design.md
for the original design doc (architecture, performance strategy, and a
roadmap whose "Phase 2" has largely shipped — the People view, Face Map, and
on-device embeddings with near-duplicate detection; only the "predict my picks"
keeper-ranking and the GPU archive-exploration renderer remain ahead).
npm test
Tests are colocated as *.test.js next to their sources under server/
and ui/src/, using Vitest. Layout and windowing
logic are pure functions, unit-tested against synthetic data; the server
API is tested end-to-end against a real ephemeral-port Express instance
with real generated images (no mocks).
MIT — see LICENSE.
JavaScript
76.7%
Svelte
23.0%
Fast, local-first photo triage. Plug in an SD card, get an instant grid, cull with the keyboard, and organize the best shots — without the slowness of Lightroom or a dead app like Picasa.
Two principles drive the design:
1–5, 0 clears) with
auto-advance, arrow-key grid navigation, a loupe (detail view) with
prefetch for instant back/forth.C to manually override which photo is the cover.v2 is stable and in active use, built on Svelte 5 (runes) with an
up-to-date dependency stack. The current version is in
package.json, and what changed in it is in
CHANGELOG.md — those are the two files that cannot go stale.
Shipped so far: folder scanning, thumbnail generation with an on-disk cache,
star ratings, the loupe, the justified + virtualized grid, burst-stack detection
with manual cover override, auto-album clustering with move/copy into dated
folders, feed filtering and grouping, a D3 timeline scrubber, tree + fisheye
sidebars, missing-files review, a persisted folder library with offline
browsing, video playback and conversion, GPS place names, on-device image
embeddings and near-duplicate detection, face detection with a browsable People
view and a Face Map, a diagnostic trace log, and Electron packaging with a
native folder picker. See docs/ROADMAP.md for the full
status and backlog (tracked in
GitHub Issues).
The two previous generations of the app are archived under
legacy/ for reference — do not run them (they contain
known insecure patterns, including the Electron anti-patterns this rewrite
deliberately avoids). They exist to port the album-clustering algorithm into
v2.
Requires Node.js >= 22.
npm install
npm run dev
This starts the Express API on http://localhost:4321 and the Vite UI on http://localhost:5173. Open the UI, paste in (or type) a folder path, and scan.
npm run electron:dev
Opens the same app in a real Electron window, with a native "Choose Folder…" button (native OS dialog) instead of typing a path.
To build an installable package for your platform:
npm run electron:build:mac # local smoke-test build (macOS) → release/
npm run electron:build # mac + win + linux (needs Wine for Windows, when run from macOS)
Builds land in release/ (e.g. AutoGallery-<version>.dmg).
AutoGallery is not signed with a paid Apple Developer ID or Windows
code-signing certificate (Apple notarization / Windows signing aren't set up —
see
docs/superpowers/specs/2026-07-06-electron-packaging-design.md).
Each OS therefore warns you the first time you open it. These are one-time steps
per download — here's how to run it anyway on each platform.
macOS (.dmg / .zip) — the app is only ad-hoc signed
(codesign --sign -, which is required so the kernel doesn't kill it on Apple
Silicon, but can't vouch for who built it):
AutoGallery.app → Open → Open in
the dialog. First launch only; after that it opens normally by double-click.xattr -cr /Applications/AutoGallery.app
(-c clears extended attributes, -r recurses into the bundle; the
com.apple.quarantine flag is what triggers the block.)Windows (.exe, NSIS installer) — unsigned, so Microsoft SmartScreen steps
in:
Linux (.AppImage) — no signing concept; just make it executable:
chmod +x AutoGallery-<version>.AppImage
./AutoGallery-<version>.AppImage
If it complains about FUSE, either install libfuse2 or run it with
./AutoGallery-<version>.AppImage --appimage-extract-and-run.
npm test # run the test suite (vitest)
npm run build # build the UI to dist/ (served by Express in production)
npm run format # prettier
| Key | Action |
|---|---|
← → ↑ ↓ | Move selection in the grid |
Home / End | Jump to first / last photo |
Enter / Space | Open the loupe (or expand/collapse a burst stack) |
Esc | Close the loupe / collapse the expanded stack |
1–5 | Rate the selected photo (auto-advances) |
0 | Clear the rating |
C | Set/unset the current photo as its burst stack's cover |
+ / - | Zoom the grid density |
ProcessingService interface (server/processing/), so the engine can be
swapped (native → WASM → Python ML sidecar) without touching the
scanner, index, or UI. server/albums/ is a pure, framework-free module
for time-gap-based album clustering.electron/main.js (ES modules) wraps the
same Express server unmodified; electron/preload.cjs stays CommonJS
(Electron's sandboxed preload loader can't run ESM — verified directly).
Security: contextIsolation, no nodeIntegration, sandboxed, exposing
exactly one contextBridge method for the native folder picker.~/.autogallery/ on your internal disk — a rebuildable cache/index, never
the source photo folders. Ratings, cover choices, the metadata cache, the
thumbnail cache, and the scanned-folders library are all stored there.See CLAUDE.md for the full set of conventions and
invariants, and
docs/superpowers/specs/2026-07-06-photo-triage-design.md
for the original design doc (architecture, performance strategy, and a
roadmap whose "Phase 2" has largely shipped — the People view, Face Map, and
on-device embeddings with near-duplicate detection; only the "predict my picks"
keeper-ranking and the GPU archive-exploration renderer remain ahead).
npm test
Tests are colocated as *.test.js next to their sources under server/
and ui/src/, using Vitest. Layout and windowing
logic are pure functions, unit-tested against synthetic data; the server
API is tested end-to-end against a real ephemeral-port Express instance
with real generated images (no mocks).
MIT — see LICENSE.
JavaScript
76.7%
Svelte
23.0%