house lights

How it works

A behind-the-scenes look at house lights

Amsterdam has an extraordinary arts scene — theatre, dance, improvised music, performance art, things that don't have a name yet. But keeping track of it is genuinely hard. Every venue runs its own website, its own calendar, its own newsletter. You either know to look, or you miss it.

house lights fixes that by scraping every venue's programme and putting it in one feed. No curation, no editorial angle — just everything, in one place, updated regularly.

The pipeline

01
Scrapers fetch venue programmes

Each venue has a dedicated Python scraper that reads its agenda page — or in some cases, calls an undocumented API. Most use httpx and BeautifulSoup. A handful of venues render their calendars entirely in JavaScript, so those use Playwright to run a real browser headlessly.

02
Shows are parsed and stored

The scraper extracts title, date, time, type, and URL for each show and writes it to a PostgreSQL database on Supabase. Duplicate shows (same title, venue, date) are skipped. A separate enrichment step fetches descriptions and images from individual show pages.

03
The frontend queries the database

The Astro frontend runs server-side on Vercel and queries Supabase directly — there is no separate API layer. Row-level security policies mean each user only ever sees data they're entitled to.

04
You see the result

Your feed is filtered by city, filtered by venues you've hidden, and sorted by date. You can bookmark shows to your watchlist, track ticket status, subscribe to a calendar feed, and follow what your friends are watching.

The stack

Frontend
Astro (SSR) · React · Tailwind CSS
Database & auth
Supabase — PostgreSQL with row-level security
Hosting
Vercel — edge-deployed, no cold starts
Scrapers
Python — httpx, BeautifulSoup, Playwright
Scraper runtime
GitHub Actions — runs weekly, logs to the repo
Security scanning
Semgrep, Bandit, njsscan, Bearer, OSV Scanner

Data freshness

Scrapers run every Monday morning. Most venues publish their full season at the start of the year, so weekly is usually more than enough. For venues that update frequently — like Paradiso or Melkweg — runs can be triggered manually when something new goes on sale.

If you notice a show is missing or a date is wrong, the most likely explanation is that the venue changed their website structure and the scraper needs updating.

Open source

house lights will be open source. The plan is to release the codebase — scrapers, frontend, and all — once the project is stable enough that the code is worth reading. If you want to write a scraper for a venue that isn't covered yet, that will be easy to contribute.

Full documentation will live at docs.houselights.claireheaded.com when the project goes public.

Missing a venue?

If there's a venue you'd like to see covered, email support@claireheaded.com. Amsterdam is the focus for now, but the architecture supports multiple cities.

AboutHow it worksPrivacy policyContact☕ Support on Ko-fi