
Planning around the map
Trainlink is a map-first trip builder for European rail. It handles multi-stop journeys, route alternatives, saved plans and editorial travel content in one experience.

Journey logic that stands alone
I built it as a pnpm and Turborepo TypeScript monorepo. Journey logic lives in standalone packages, separate from the Next.js and React interface, so the core rules aren’t tied to any screen.

From raw timetables to routable data
A Python feed pipeline turns publisher timetable archives into validated artifacts, station bindings, city routing data and a published rail snapshot. A self-hosted MOTIS timetable engine handles routing.

Running it in production
The service runs on an Oracle Cloud VM with Docker, Coolify and Caddy, using Cloudflare DNS and R2 and Neon Postgres and Auth. A token-protected gateway guards routing, and blue/green releases roll out new timetables.
