English · Français
Got a GPX file — the track of a race? Trailcli reads it and tells you everything that matters: distance, elevation, the nastiest climbs, pace, kilometer splits… whether you're prepping a race that's coming up 🗺 or debriefing the one you just ran 🏅. Got a season of activities? Feed it a Garmin Connect CSV export and Trailcli sums up your training history 📊.
No website, no account to create, nothing sent anywhere. One command, and it all shows up in a clean, keyboard-driven interface.
- 🗺 PLAN mode — prep an upcoming race: tough zones, demanding segments, recommended pace
- 🏅 RACE mode — debrief a finished run: duration, pace, splits, best and worst km
- 📊 HISTORY mode — feed it a Garmin Connect CSV export: monthly volume, pace trend, personal records
- 📈 Readable charts — elevation profile, monthly volume and pace trend drawn with graduated axes
- ⌨️ 100% keyboard — vim-style navigation, shortcuts always shown at the bottom
- 🔒 100% local — everything is computed on your machine, no connection, no account
- 📤 JSON export — dump the raw stats to plug them in elsewhere
Trailcli runs on macOS, Windows, and Linux. You need Python 3.11+ and pipx. Two minutes, once.
Check if you already have it:
python3 --versionIf it prints Python 3.11 (or newer), skip to step 2. Otherwise grab it from python.org/downloads and install it.
💡 On Windows, tick the "Add Python to PATH" box at the start of the installer.
pipx installs Python apps cleanly, without messing up your machine.
| OS | Commands |
|---|---|
| macOS | brew install pipxpipx ensurepath |
| Windows | py -m pip install --user pipxpy -m pipx ensurepath |
| Linux (Debian/Ubuntu) | sudo apt install pipxpipx ensurepath |
| Linux (other) | python3 -m pip install --user pipxpipx ensurepath |
Close and reopen your terminal after this step.
pipx install trail-cliThat's it! The trailcli command is now available everywhere. To check:
trailcli --helpDon't want to bother with pipx? You can also run
pip install trail-cli, or grab the bleeding edge straight from GitHub:pipx install git+https://github.com/jherduin/trail-cli.git
Easiest path: just launch Trailcli with no arguments — an interactive menu pops up:
trailcliYou can also do everything in one line:
| Command | What it does |
|---|---|
trailcli |
Opens the interactive menu (easiest) |
trailcli my-race.gpx |
Loads the file and asks for the mode |
trailcli my-race.gpx --plan |
Prep an upcoming race |
trailcli my-race.gpx --race |
Analyze a race you already ran |
trailcli my-race.gpx --json |
Dump the stats as JSON (no interface) |
trailcli activities.csv |
Opens HISTORY mode on a Garmin Connect CSV export |
The file type is detected automatically: a
.gpxopens PLAN/RACE, a.csv(Garmin Connect export) opens HISTORY. You can also pick either one from the interactive menu.
Want to try it right now? Sample files are included:
trailcli tests/fixtures/utmb.gpx --race # a race with timing data
trailcli tests/fixtures/no_time.gpx --plan # a track with no timing dataWhere do I find a GPX file? On a race organizer's website, by exporting a Strava segment, or from your watch (Garmin, Coros, Suunto…) / your app (Strava, Komoot) after a run.
You've got the GPX of a future race and you want to build your strategy. Trailcli shows you:
- The key numbers: distance, elevation gain (D+) and loss (D−)
- The course profile, with the tough zones highlighted (the big climbs)
- The most demanding segments: climbs and descents, with their length, grade, and an estimated duration
- The recommended pace by terrain (flat, moderate climb, steep climb, descent)
- The watch-outs: the summit, the longest single climb, how the course finishes
You've exported your run from your watch or Strava. Trailcli shows you:
- The key numbers: distance, D+, D−, real duration, average pace
- The profile colored by pace: green where you were fast, red where you slowed down
- Your kilometer-by-kilometer splits, with your best and worst km called out
If your file has no timing data (just a track), Trailcli still shows all the terrain stats — it simply hides whatever depends on the clock.
Export your activities from Garmin Connect as a CSV and hand the file to Trailcli (trailcli activities.csv). Instead of a single race, you get the big picture of your season across four tabs:
- Overview: totals (number of activities, distance, elevation) and your headline numbers
- Volume: monthly distance as a bar chart, with the busiest month highlighted
- Pace: your average-pace trend over time, fast (green) to slow (red)
- Records: your personal bests — longest run, fastest pace, biggest elevation gain, and longest streak of consecutive days
Everything is keyboard-driven. The handy shortcuts are always shown at the bottom of the screen.
| Key | Action |
|---|---|
↑ ↓ (or j k) |
Navigate / scroll |
tab / shift+tab |
Next / previous tab |
h / l |
Previous / next tab (vim) |
p |
Toggle between PLAN and RACE (same file) |
r |
Reload the file |
e |
Export stats as JSON |
? |
Show the shortcuts help |
esc |
Go back |
q |
Quit |
The GPX file is parsed once at launch, then the result feeds the whole interface. The main calculations:
- Distance: the Haversine formula between successive points
- Elevation: sum of the climbs (D+) and the descents (D−)
- Terrain type: climb (> +4%), descent (< −4%) or flat, with smoothing to absorb GPS noise
- Estimated pace: Naismith's rule, adjusted for elevation
The charts (elevation profile, monthly volume, pace trend) are drawn with plotext so they get graduated axes and stay readable right in the terminal.
Built with Typer (CLI), Textual (interface), gpxpy (GPX reading), Rich (rendering) and textual-plotext (charts). Python 3.11+, no database, no server, no browser.
I don't see any duration or pace. That's because your GPX file has no timing data (some tracks only carry the route). All the terrain stats are still there.
Is my data sent anywhere? Nope. Everything is computed locally on your machine. No connection, no account.
How do I uninstall?
pipx uninstall trail-cliThe project is open source and built to be improved by the trail community. To work on it locally:
git clone https://github.com/jherduin/trail-cli.git
cd trail-cli
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
python -m pytest # run the tests
ruff check . # check the styleWe follow the one task = one branch = one PR rule, with commits in the Conventional Commits format. Contributions are welcome!
MIT — free to use, modify, and share.