Strava Local
Local-first fitness analytics, your data stays on your machine
Overview
A local ingestion and analysis tool for Strava activity data. Import your Strava export, CSV metadata and FIT files, into a local SQLite database for analysis and visualization. All data stays local. Your activity data, GPS tracks, and training metrics are never uploaded anywhere.
The Problem
I wanted to understand how training metrics actually work, not just see numbers, but compute them myself. Strava shows you TSS and fitness curves, but I wanted to dig into the formulas, experiment with different calculations, and query my data in ways the app doesn't support. Building this gave me a deeper understanding of training science and a local archive of years of activity data I can explore however I want.
What I Built
- — FIT file parser that extracts GPS streams, heart rate, altitude, and cadence from years of activity data
- — SQLite database with normalized schema for activities, streams, and computed metrics
- — Dashboard with summary statistics, activity breakdown charts, and recent activity feed
- — Interactive heatmap and route explorer with activity type and date filters
- — Training metrics engine: TSS, TRIMP, intensity factor, and time-in-zone calculations
- — Fitness modeling with daily CTL/ATL/TSB (chronic training load, acute training load, training stress balance)
- — Athlete settings for personalized calculations: max HR, LTHR, resting HR, FTP, weight
- — CLI tools for data ingestion, metric computation, and map generation
Key Decisions
SQLite was the obvious choice, the entire point is local-first simplicity, and it handles years of activity data without breaking a sweat. Flask + Jinja2 keeps the stack minimal and dependency-light. Leaflet with OpenStreetMap tiles over Mapbox because there's no API key to manage and no usage billing to worry about. GPS routes are downsampled to 500 points max to keep storage reasonable without losing visual fidelity.