A static site generator that builds a photography portfolio website from your Adobe Lightroom albums. Written in Go with an optional TypeScript sync command for persisting data to Supabase and uploading images to Google Cloud Storage.
- Fetches albums and photos directly from the Adobe Lightroom API
- Generates a fully static website with responsive masonry grid layouts
- Dark and light theme support (respects system preference)
- Built-in lightbox with EXIF metadata display
- Concurrent image downloading with smart caching
- OAuth2 authentication with automatic token refresh
- Optional sync to Supabase (PostgreSQL) and GCP Cloud Storage
- Go 1.24+
- Node.js 18+ (only for the sync command)
- Adobe Lightroom API credentials (Adobe Developer Console)
git clone https://github.com/sonu27/lightroom-site-generator.git
cd lightroom-site-generatorCreate a .env file:
LIGHTROOM_CLIENT_ID=your_client_id
LIGHTROOM_CLIENT_SECRET=your_client_secretgo run ./cmd/loginThis opens your browser for OAuth2 authentication and saves tokens to .token.json.
go run ./cmd/generateThe static site is output to the site/ directory (configurable via LIGHTROOM_OUTPUT_DIR). A site-data.json file is also produced for use by the sync command.
npm install
npm run syncThis uploads images to GCP Cloud Storage and syncs album/photo metadata to Supabase.
site/
index.html # Latest photos
albums.html # Album grid with cover images
{album-slug}.html # Individual album pages
about.html
contact.html
static/
main.css, main.js, lightbox.css
images/
{album-id}/
{asset-id}.jpg # Photos at 2048px (longest edge)
All configuration is via environment variables (or .env file):
| Variable | Required | Default | Description |
|---|---|---|---|
LIGHTROOM_CLIENT_ID |
Yes | — | Adobe API client ID |
LIGHTROOM_CLIENT_SECRET |
Yes | — | Adobe API client secret |
LIGHTROOM_BEARER_TOKEN |
No | — | Direct bearer token (alternative to OAuth2) |
LIGHTROOM_REFRESH_TOKEN |
No | — | Set automatically after login |
LIGHTROOM_TOKEN_EXPIRY |
No | — | Set automatically after login |
LIGHTROOM_OUTPUT_DIR |
No | site |
Output directory for generated site |
LIGHTROOM_SITE_TITLE |
No | Photography Portfolio |
Site title |
LIGHTROOM_CATALOG_ID |
No | Auto-detected | Specific Lightroom catalog ID |
LIGHTROOM_FORCE_REDOWNLOAD |
No | false |
Force re-download of all images |
SUPABASE_URL |
Sync only | — | Supabase project URL |
SUPABASE_SERVICE_ROLE_KEY |
Sync only | — | Supabase service role key |
GCP_PROJECT_ID |
Sync only | — | Google Cloud project ID |
GCP_BUCKET_NAME |
Sync only | — | Cloud Storage bucket name |
GOOGLE_APPLICATION_CREDENTIALS |
No | Default creds | Path to GCP service account JSON |
SKIP_GCP_UPLOAD |
No | false |
Skip GCP image upload |
cmd/
login/ # OAuth2 authentication (Go)
generate/ # Site generation (Go)
sync/ # Supabase + GCP sync (TypeScript)
internal/
config/ # Configuration
fetcher/ # Lightroom API data fetching
generator/ # Static site generation engine
lightroom/ # Lightroom API client
view/ # HTML templates and static assets
Adobe Lightroom API
│
▼
go run ./cmd/login ← OAuth2, saves .token.json
│
▼
go run ./cmd/generate ← Fetches data, generates static site
│
├──▶ site/ ← Static HTML, CSS, JS, images
├──▶ api-resp.json ← Cached API response
└──▶ site-data.json ← Structured metadata
│
▼
npm run sync ← Uploads images, syncs metadata
│
├──▶ GCP Cloud Storage
└──▶ Supabase (PostgreSQL)
# Build Go binaries
go build ./cmd/generate
go build ./cmd/login
# Build TypeScript
npm run build
npm run build:watch # Watch mode
# Tidy dependencies
go mod tidy