Visualize your Strava activities as progress along any GPX route. Built with Agentic Engineering using Claude.ai and Claude Code.
Road to X connects to your Strava account, sums your activity kilometers, and places a marker at the exact point you would have reached on a GPX route of your choice.
No GPS matching. No location tracking. A 40 km ride in Hamburg moves your marker 40 km closer to Lisbon.
My personal goal: Cycle 2,578.8 km between May 1 and September 30, 2026 — the distance from Frankfurt to Restaurante Ponto Final in Lisbon, with a view of the Ponte 25 de Abril and the Tagus river.
| Feature | Description |
|---|---|
| Progress Map | Leaflet.js map with GPX route. Completed in dark blue, remaining in terracotta. |
| Stats Dashboard | Distance, elevation, time, activity count — actual vs. plan. |
| Smart Filters | Sport type + time period (3M/6M/1Y/All or custom date). State persists in DB. |
| Forecast Chart | Distance-over-time projection with plan speed slider and spread tunnel. |
| Analysis Tabs | Elevation profile and pace chart. |
| Street Preview | Mapillary — nearest street photo to your current route position. |
- Backend: Node.js + Express
- Database: sql.js (SQLite, pure JS — zero native dependencies)
- Auth: Strava OAuth 2.0
- Maps: Leaflet.js + leaflet-gpx
- Charts: Chart.js + native Canvas API
- Upload: multer (memoryStorage)
- Street View: Mapillary API
Clone the repo and install dependencies:
git clone https://github.com/paseitz225/road-to-x
cd road-to-x
npm install
cp .env.example .env
Fill in your credentials in .env, then start the server:
npm start
App runs at http://localhost:3002
STRAVA_CLIENT_ID= # From https://www.strava.com/settings/api
STRAVA_CLIENT_SECRET= # From https://www.strava.com/settings/api
STRAVA_REDIRECT_URI=http://localhost:3002/auth/callback
SESSION_SECRET= # Any random string
MAPILLARY_TOKEN= # From https://www.mapillary.com/developer
PORT=3002
Upload GPX Route → Connect Strava → Filter Activities → Sum Distances → Place Marker
The algorithm finds the GPX waypoint closest to your total filtered distance and places a marker there.
This project was built without writing a single line of code manually.
- Claude.ai — Planning, architecture, user stories, wireframes, data flow
- Claude Code — Implementation, file system, git, database
- Agent Team Framework — PO, Developer, Tester A (API), Tester B (blind E2E), Mentor (retrospective)
src/
├── server.js
├── routes/
│ ├── auth.js # Strava OAuth
│ ├── activities.js # Activity sync + cache
│ ├── routes.js # GPX upload + progress
│ ├── settings.js # Filter state persistence
│ └── share.js # Public share links
└── db/
├── connection.js # sql.js setup + persist
├── init.js # Schema + migrations
└── reset.js # Dev reset utility
public/
├── progress.html # Meine Reise (main view)
├── dashboard.html # Meine Aktivitaeten
├── upload.html # Meine Route
└── login.html
- Onboarding Wizard
- Multi-Journey support (multiple parallel routes)
- Public share links + iframe embeds
- Demo mode (no Strava account needed)
- Agent Framework v2 (Data Critic + UX Critic)
Contributions welcome — new route types, Strava integrations, UI improvements, or extending the agent team framework.
MIT
Built by Patrick Seitz — patrick-seitz@gmx.de — May 2026
