Overview
I built this tracker while preparing for the Stockholm Marathon to get a clearer view of how my actual training compared with the plan I was following. Instead of keeping planned workouts and completed runs separate, the page brought them together in the same calendar. Each day could show the distance, time and pace from a recorded run or walk, while the recommended workouts for that part of the training plan were shown alongside it. Activities also linked back to their original Strava entries, making the tracker a simple overview of both the plan and the training that actually happened.
Architecture & Implementation
The project started as a way to turn a static marathon training plan into something more useful during the months leading up to the race. The application was served through a small Express backend using Handlebars, while most of the calendar logic ran directly in the browser with JavaScript.
flowchart LR
subgraph WebApp[Web application]
direction TB
interface[Training calendar<br/>interface]
subgraph Data[Web application data]
direction LR
plan[(Training plan<br/>JSON)]
activities[(Activity JSON)]
end
end
subgraph Strava[Strava]
direction TB
api[Strava API]
profile[Strava profile with activities]
end
interface -->|Links to Strava| profile
Data <-->|Checked and updated<br/>with a Raspberry Pi| apiThe activity data was kept up to date automatically through a Raspberry Pi, which checked Strava for new runs every five minutes. When a new activity was found, it was added to the JSON file used by the tracker and marked as processed so that it would not be added again during later checks. This allowed new Strava activities to appear on the web page automatically, without requiring the training data to be updated manually.
From there, the calendar was generated dynamically using JavaScript date calculations. Four weeks were displayed at a time, with controls for moving forwards and backwards through the training period. Each day was matched against the activity data, allowing completed runs and walks to appear directly inside the calendar. Recorded activities showed information such as distance, moving time and average pace, and the date linked back to the original activity on Strava. Walks were handled slightly differently and were displayed without a pace value.
The planned side of the tracker followed the same timeline. Each training week contained a set of recommended sessions, such as speed work, recovery runs and long runs, together with short descriptions and interval details where needed. These recommendations were selected based on the number of weeks remaining before race day, so moving through the calendar also moved through the corresponding stages of the training plan.
The calendar also included visual markers for dates such as race day and the current date. The project was built specifically around the 2025 Stockholm Marathon, so the race date and training plan were fixed to that event. Some countdown functionality for weeks and days remaining was still present in the code, although it was no longer shown in the interface.