galr

Self-hosted private image gallery for browsing large photo collections organized in a flexible hierarchy.

Case study: Case study: galr (self-hosted gallery)

Highlights

  • Zero-dependency architecture: single Node.js process, no external database or cache
  • Advanced lightbox with slideshow, pan/zoom, keyboard shortcuts, and collection navigation
  • Comprehensive organization: tags, ratings, favorites, notes, and smart filtering
  • Secure sharing via time-limited token URLs with automatic session management
  • Invite-only registration with QR code system for frictionless onboarding

A self-hosted private image gallery built for browsing large photo collections organized in a flexible hierarchy (e.g., category → collection → images). Runs as a single Node.js process with no external dependencies.

What it is

A private gallery for organizing and browsing large photo collections. Category list with grid view, collection pages with lightbox, tags and ratings for organization, secure time-limited sharing, and invite-only access control.

Designed for use cases like: organize photos by Year → Month → images, or Travel → Destination → images. Flexible hierarchy mirrors your filesystem structure.

Architecture

Single-process design: Node.js with embedded SQLite (using --experimental-sqlite). No separate database server, no Redis, no complex orchestration.

Server-side rendering: Hono JSX for HTML generation, minimal vanilla client JS for interactivity.

Lazy thumbnails: Sharp generates thumbnails on first access and caches them. Configurable TTL for automatic cleanup.

Key features

  • Browsing: Category list with filters, collection grids, lightbox with prev/next/slideshow/zoom, search with typeahead
  • Organization: Tags (category & collection level), 1–5 star ratings, favorites, freeform notes
  • Sharing: Time-limited (7-day) token URLs for sharing collections without requiring login
  • Admin: Incremental scan, orphan pruning, thumbnail cache management, QR code invite system
  • Security: Session-based auth, HTTP-only cookies, invite-only registration

Tech stack

Runtime: Node.js 24 with --experimental-sqlite (native SQLite support)

Server: Hono v4 + @hono/node-server (HTTP + SSR)

Database: node:sqlite (DatabaseSync) in WAL mode

Thumbnails: Sharp for JPEG generation

Client: Vanilla JS (<10KB), no build step

Status

Currently running in private testing. Functional and stable for daily use with 5,000+ images across 200+ collections.