🔗

Lynx

GoTemporalPostgreSQLKafka

Lynx is my personal link and feed manager — a self-hosted service for saving, organising, and enriching URLs and RSS/Atom feeds without handing that data to a commercial platform.

I wanted to own my reading list. When a URL is saved, a Temporal workflow fetches the page, extracts metadata (title, description, Open Graph tags, language, author, canonical URL), and archives the raw HTML and readable text to object storage. Each new link is also published as a Kafka event so the rest of my platform — search, cataloguing, RAG — can pick it up without tight coupling.

Lynx is a personal link and feed management service — a place to save, organise, and enrich URLs and RSS/Atom feeds without handing that data to a commercial read-later or bookmarking platform.

Why I Built It

I wanted to own my reading list. Existing bookmarking tools work well enough, but they’re third-party services with their own retention and privacy trade-offs. Lynx runs on my own infrastructure and stores everything in a PostgreSQL database I control.

It also gave me a realistic project to practice building an asynchronous enrichment pipeline: when a URL is saved, a Temporal workflow fetches the page, extracts metadata (title, description, Open Graph tags, language, author, canonical URL), archives the raw HTML and readable plain-text to object storage, and writes the enriched record back to the database.

What It Does

  • Website/bookmark tracking — store and browse URLs with deterministic UUID v5 deduplication on the normalised URL, so saving the same link twice is safe.
  • Feed management — track RSS/Atom feeds and link them to a parent website.
  • Automatic enrichment — on creation, a Temporal workflow fetches, parses, and archives each URL in the background.
  • Magpie integration — each new website is published as a magpie.v1.Resource Kafka event so downstream services (search index, graph DB, etc.) can pick it up without tight coupling.
  • Bulk import — the CLI reads a Markdown file of bullet-point URLs and creates website records for all of them in one shot.

Tech Stack

  • Backend: Go, ConnectRPC, PostgreSQL
  • Workflow orchestration: Temporal
  • Messaging: Kafka (Redpanda in local development)
  • Object storage: MinIO (S3-compatible)
  • Frontend: WebAssembly SPA written in Go using go-app

For a deeper look at how the pieces fit together, see ARCH.md.

Documentation