DEV Community

Cover image for I Ditched iCloud Photo Sharing and Built My Own (with an AI partner)
Doug Donohoe
Doug Donohoe

Posted on

I Ditched iCloud Photo Sharing and Built My Own (with an AI partner)

iCloud shared albums take 26+ seconds to load on my 300 Mbps fiber connection. I timed it. Apple, a trillion-dollar company, built something that is embarrassing to show people.

Other photo sharing sites have their own irritations like cumbersome UIs, advertising, hawking of photo paraphernalia and social media distractions. I just want to share photos with friends and family. Focus on the photos.

So I built DD Photos, an open-source static photo gallery generator. It's what runs photos.donohoe.info (it's wicked fast). And I built it almost entirely with Claude Code. The first version, which I shared with family, only took a few days. I've been gradually improving it for over six weeks now.

The Stack

  • Gophotogen, the CLI tool that resizes JPEGs to WebP (600px grid / 1600px full), strips EXIF metadata (no GPS leaks), and generates JSON index files for each album. Concurrent processing via goroutines.
  • SvelteKit — statically generated frontend. Fetches the JSON indexes client-side. No server-side code, no database.
  • PhotoSwipe — lightbox with swipe support, keyboard navigation, permalink-per-photo
  • Deploymentrsync to Apache/EC2 or aws s3 sync to S3+CloudFront. It's just files.

The result is genuinely fast because there's nothing dynamic happening at request time. It's a CDN serving HTML, JS, and WebP images.

How It Works

You already use something to curate photos: Lightroom, Apple Photos, Google Photos, whatever. Export a folder of JPEGs. That folder is an album. Point photogen at it:

# Dry run first
go run cmd/photogen/photogen.go -resize -index -clean

# For real
go run cmd/photogen/photogen.go -resize -index -clean -doit
Enter fullscreen mode Exit fullscreen mode

This produces resized WebP files and JSON index files consumed by the SvelteKit frontend. Then build the static site and deploy.

Configuration is primarily in two files: albums.yaml (album list and photo paths) and descriptions.txt (album descriptions).

Features Worth Noting

  • Password-protected albums with in-browser decryption via the Web Crypto API. Passwords are never stored server-side.
  • Per-photo captions via photogen.txt, used as alt text, hover captions on desktop, always-visible on mobile.
  • Hero image with configurable crop position.
  • OpenGraph tags for rich link previews in iMessage, WhatsApp, Slack.
  • Dark/light theme toggle.
  • Custom CSS override without forking the source.
  • Shareable permalinks per photo (e.g. /albums/patagonia/5).
  • Recursive album support for nested directory structures.

The Claude Code Experience

I want to be honest about what it was actually like, because the hype around AI coding tools often glosses over the rough edges.

The good: Claude handled the bulk of the implementation work. The first working version of photogen, over a day's worth of Go work, took nine commits. The SvelteKit frontend, lightbox, keyboard nav, and mobile layout: another handful of commits. Two days from first commit to sharing a live URL with friends and family. For someone who hasn't touched SvelteKit before, that's remarkable.

The less good: Claude has no memory between sessions (the 50 First Dates problem). You have to re-establish context constantly. It also tends toward confident single-mindedness when debugging. It'll reason through a problem, make a change, and declare victory, when the right move was to write a failing test first. I had to prompt that explicitly.

It also occasionally produces code that duplicates existing logic it wrote itself. I caught an 80% duplication in the JPEG cover photo code and had to ask for a refactor. A senior developer would have done that on the first pass.

My conclusion: Claude Code is a genuine force multiplier for experienced developers. I knew the architecture I wanted, I recognized bad patterns when I saw them, and I could ask pointed questions when things went wrong. A novice would have struggled. A senior dev gets maybe 10x throughput on a project like this.

The Open Source Push

The initial build was pretty rough as a public project: album configs hard-coded in Go, docs written for an audience of one (me), no sample app. Getting it release-ready took another week of work: externalizing configuration, writing proper docs, creating a sample site with sample albums, extracting from a private monorepo. That was version 1.0. I'm now at version 1.9, having spent another month and a half continuously improving things.

The HISTORY.md in the repo logs over 60 Claude Code sessions across the project's lifetime, if you want to see the full arc of how something like this gets built incrementally with an AI pair programmer.

Try It

git clone https://github.com/dougdonohoe/ddphotos
cd ddphotos

# Install deps (Mac)
brew install go vips pkg-config
go mod download
make web-nvm-install && make web-npm-install

# Run the sample site
make sample-photogen
make sample-npm-run-dev
Enter fullscreen mode Exit fullscreen mode

It's AGPL v3 licensed. If you build something with it or have questions, I'd love to hear about it.


I wrote a longer version of this story (more travel photos, more Claude opinions) on Medium if you want the full picture.

Top comments (0)