Kevin Rich

Software Engineering Leader

Building ai-driven, cloud-native applications — and the high-performing engineering teams that ship them.

Kevin Rich
All projects

A self-hosted personal video media server that reads each file's own embedded metadata as the source of truth, built in Go with a SvelteKit frontend.

Go SvelteKit TypeScript SQLite Tailwind CSS Docker GitHub Actions Claude Code
v1.12.1 updated 3 days ago

Most media servers make you bend your library to fit them. You rename files to a scheme, maintain a database by hand, or hand your collection to an online service to scrape. Holodex takes the opposite stance. The metadata already embedded in your video files is the catalog: titles, cast, genres, and dates written into the container’s iTunes atoms or Matroska tags. Point it at a folder and it indexes everything with no naming conventions, no internet connection, and no telemetry.

Media is a long-running hobby of mine and my university minor, and I’ve built versions of this project for years. This time I paired with Claude Code and reached a working MVP in a few days. Previous attempts took weeks. I deliberately chose Go because I’d never used it before; in practice my approach left me little need to drop into the Go code by hand.

The backend is a single pure-Go binary running a chi REST API on top of SQLite. The frontend is a SvelteKit SPA on semantic design tokens driving three fully switchable skins from a single header control. Notable technical decisions:

  • Incremental indexing: the scanner only re-reads files whose mtime or size changed; rescanning an unchanged 10k-file library makes zero subprocess calls
  • Full-text search with FTS5: diacritic-folded, so amelie finds Amélie
  • Tiered cover art: embedded poster art pulled at index time; files without it get a throttled background frame thumbnail
  • Open enrichment protocol: provider sidecars speak four HTTP endpoints; a TMDB reference implementation ships alongside the core
  • Unified field resolution: file-embedded and provider values merge per canonical field with source attribution preserved
  • Metadata writeback: operators write the winning value back into the source file’s own tags via an exiftool copy, write, and atomic rename

It’s built to be run, not hosted-for-you. The library mounts read-only, the index and config live in a named volume, and the whole thing ships as one multi-arch image (amd64 + arm64) for NAS and ARM home servers. Additional capabilities:

  • MCP server handing the library to AI assistants
  • System Activity panel for indexing internals
  • Provenance-tracked enrichment history per field

Architecture decisions are tracked as a numbered ADR series in the repo.

A personal book-tracking app for owned and wishlist books, built with React, Hono, and DynamoDB on AWS.

React TypeScript Hono AWS CDK DynamoDB Cognito WebAssembly
v0.7.0 updated 12 days ago

Bookshelf is a personal book-tracking app — organize what you own and what you want to read across owned and wishlist shelves, search by title, ISBN, or ASIN, and build custom smart shelves from saved filters.

Barcode and ISBN-text scanning use a tiered fallback: native BarcodeDetector/TextDetector browser APIs where available (zero bytes, hardware-accelerated), a lazily-loaded, self-hosted WASM decoder (zxing-wasm for barcodes, Tesseract.js for OCR) on iOS Safari where those APIs don’t exist, and a server-side AWS Rekognition OCR fallback as a last resort. The rest of the stack is a React SPA (Vite + Tailwind) on S3/CloudFront, a Hono API on Lambda behind API Gateway backed by a single-table DynamoDB design, and Cognito auth with blue/green pool migrations for zero-downtime identity changes.

Built solo, end-to-end, working alongside Claude Code — specs and architecture decisions are written before implementation and kept as ADRs in the repo. A separate MCP server exposes the same functionality so an AI assistant can query and update a shelf directly, and the whole stack — three CDK stacks, GitHub Actions CI/CD with OIDC, semver-tagged deploys — is defined as code.

Notes on engineering decisions, AWS, and things I've learned building.

Visit blog