Your photos, on your own server.

PhotoStack is a small, self-hosted photo library. Drop in your photos and it reads when and where they were taken, builds a timeline, puts them on a map and finds duplicates.

The demo is read-only and uses freely licensed photos from Wikimedia Commons. On the free tier it sleeps when idle, so the first visit can take up to a minute.

PhotoStack timeline: photos grouped by day, each keeping its real shape

Everything a photo library needs. Nothing it doesn't.

No accounts to sync, no cloud, no AI required. Point it at your photos and it does the rest.

Every detail, read for you

Date, camera, lens, aperture, shutter and ISO straight from the file, the street address from the GPS position, and the albums it belongs to. iPhone HEIC photos and phone videos included.

Photo viewer with an info panel: camera, exposure, address and integrity check

Your trips, on a map

Every photo with a location becomes a pin. Zoom in on a city and see what you shot there.

World map with clusters of photos in India, Portugal, the Netherlands and Iceland

Albums that make themselves

A month-by-month album for everything you've shot, plus your own albums for trips and occasions.

Albums page with custom albums and automatic month albums

Knows what needs fixing

Files that couldn't be read, photos without a date or a location, duplicates wasting space, and files that were edited or carry hidden data. Each with a link to the photos behind it.

Library health page listing photos without a date, without a location, and duplicates

Search

By place, camera, tag or file name. Every word has to match.

Duplicates

Finds copies even when resized or re-saved, and keeps the original.

Integrity checks

Real file type, SHA-256, editing software, data hidden after the image.

Videos

MP4, MOV and WebM with thumbnails, duration, date and place.

Light and dark

Works on desktop and phones, with a dark mode that remembers you.

Optional AI tags

Off by default. Add a Gemini key to get descriptive tags, nothing else changes.

How it works

One Python process, one folder of photos, one database file. Small enough to read in an afternoon.

  1. You add a photo. Upload it, or drop it in the photos folder.
  2. It's checked. The real file type must match its extension; exact copies are refused.
  3. It's read. EXIF date, camera and GPS, a 400px thumbnail, and a visual fingerprint for duplicates.
  4. It's placed. The GPS position becomes a street address (OpenStreetMap). Optional AI tags come last, so they can never break anything.

FastAPI, SQLite and React. Read the architecture notes for the data model and the reasoning behind each design decision.

See it with real photos

32 photos from eight cities, with dates, cameras and locations. Click around; you can't break it.

Open the live demo →