
jseek.co
A watchlist-style aggregator for company career pages.
Origin
When I started applying for jobs in Switzerland I quickly exhausted the pool of postings my profile suited. My fallback became a daily ritual: open the career pages of every company I knew was hiring in roles I wanted, scan, close, repeat. Twenty-plus tabs at any given time, much of the same content from yesterday.
So I built a scraper for myself. It re-ran every morning and replaced an hour of clicking with thirty seconds of reading. The first version was a small Streamlit app — job-seek — built fast and just for me.
It worked well enough that I figured the daily-monitor habit was the actual product, not the scraper underneath it. jseek.co is that habit, productised.
What it is
A watchlist-style aggregator. You pick a set of companies; jseek monitors their career pages and feeds new postings into one place. The opposite of spray-and-pray: it powers a “wait for the right opportunity” approach to the search.
How it’s built (short)
- Crawler — Python (asyncio, httpx, redis). Per-board monitors fan out scrape tasks; a Lua-backed Redis queue schedules them. CPU work and R2 staging happen in workers.
- Storage — Local Postgres is the system of record; a CDC-style exporter pushes deltas to Supabase + Typesense.
- Search — Typesense for everything user-facing (typeahead, browse, watchlist filters). Postgres only handles auth and the full posting blob.
- Frontend — Next.js on Vercel with Drizzle ORM, Better Auth, and Lingui for i18n.
Status
In active development. Companies are added by community-contributed agents resolving open company-request issues — the contribution flow uses a small CLI (ws) that walks an LLM agent through the per-company setup and verifies the work before opening a PR.
The Streamlit prototype, viktor-shcherb/job-seek, is preserved as the prequel: the working artefact that proved the daily-monitor habit was worth productising.