惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Stack Overflow Blog
Stack Overflow Blog
量子位
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
美团技术团队
小众软件
小众软件
aimingoo的专栏
aimingoo的专栏
Recent Announcements
Recent Announcements
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Microsoft Security Blog
Microsoft Security Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
酷 壳 – CoolShell
酷 壳 – CoolShell
J
Java Code Geeks
V
V2EX
大猫的无限游戏
大猫的无限游戏
D
DataBreaches.Net
博客园 - Franky
爱范儿
爱范儿
T
Tailwind CSS Blog
A
About on SuperTechFans
Google DeepMind News
Google DeepMind News
博客园_首页
B
Blog RSS Feed
博客园 - 司徒正美
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
I Ditched iCloud Photo Sharing and Built My Own (with an ...
Doug Donohoe · 2026-04-23 · via DEV Community

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.