How I built an interactive atlas of 767 train routes (React + MapLibre + open data) A developer built TrainRouter, a free interactive map of 767 notable train routes across 118 countries using React, MapLibre GL JS, and open data. The project prerenders ~1,500 static HTML pages for SEO and AI crawler discoverability, and includes features like centripetal Catmull-Rom spline smoothing and content-hashed lastmod dates. The underlying route data is published as open data on GitHub. I spent a summer building TrainRouter https://trainrouter.com — a free, no-signup interactive map of 767 of the world's notable train routes across 118 countries , from the Glacier Express and the Trans-Siberian to the new night trains stitching Europe back together. Every line carries its distance, fastest journey time, top speed, operator, rolling stock and a short story. It's a solo project, and the interesting engineering wasn't the map — it was everything around it: keeping 700+ routes fast, making a JavaScript map discoverable by search engines and AI crawlers, and turning the whole thing into open data. Here's how it went together. Everything derives from one flat list of routes. Each record is deliberately boring: id, name, from, to, category, train, operator, distance km, top speed kmh, duration, opened, pax per year, countries iso, highlight, fame rank category is one of high-speed · classic · night · scenic , which drives the colour-coding. fame rank 1 = most famous is a hand-curated renown ordering — it decides what you see first when the map is zoomed out, so the Shinkansen and the Orient Express surface before a regional branch line. The geometry is separate: a hand-traced LineString of lon/lat waypoints per route. I smooth those with a centripetal Catmull-Rom spline rather than a plain Catmull-Rom — the centripetal variant never overshoots hairpins like the Glacier Express' Chur reversal, which a naive spline turns into a loop. The map is MapLibre GL JS https://maplibre.org on OpenFreeMap vector tiles — a free, no-API-key, OpenStreetMap-based tile host. That combination means the whole map costs nothing to run and has no per-tile billing surprise. Two things that mattered for making 700+ overlapping lines readable: A single-page app is invisible to crawlers that don't run JavaScript — which includes most AI crawlers. My homepage was a