Open Source & Self-Hosted

Share your trails
with beautiful maps

Upload a GPX file, get a shareable link. Interactive 2D maps, elevation profiles, and 3D terrain flythroughs β€” all in a single Go binary.

View on GitHub Quick Install
Features

Everything you need to share a trail

No third-party services. No accounts. Just a URL.

πŸ—ΊοΈ

Interactive 2D Map

OpenStreetMap-powered map with the trail rendered as a polyline. Hover to see elevation and distance at any point.

πŸ”οΈ

3D Terrain View

WebGL terrain rendering with satellite, topographic, street, and dark basemap styles. Real elevation data, 1.5Γ— exaggerated for impact.

▢️

First-Person Playback

Animated camera follows the trail at 1Γ—, 2Γ—, 5Γ—, or 10Γ— speed. Scrub to any position along the route.

πŸ“Š

Elevation Profile

Chart.js elevation profile synced with the map cursor. Collapsible panel keeps the map front and centre.

πŸ“

Trail Statistics

Distance (Haversine), total elevation gain, and duration (when GPX timestamps are present) shown at a glance.

πŸ”—

Persistent Share URLs

Each trail gets a UUID-based URL. Map position, 3D mode, and playback state are encoded in query params for bookmarking.

πŸ“€

Drag-and-Drop Upload

Simple web UI with API key stored in browser storage. Or use curl for scripted uploads.

πŸš€

Single Binary Deploy

Go backend embeds the built frontend. Drop one binary, set one env var, done. SQLite for metadata, filesystem for GPX files.


How it works

Upload. Share. Explore.

Three steps from GPX file to 3D terrain flythrough.

1

Upload your GPX file

Drag and drop onto the web UI or curl -F file=@trail.gpx to the /upload endpoint with your API key. The server stores the file and returns a unique URL.

2

Get a shareable link

A UUID-based URL like https://trails.example.com/550e8400-... is yours instantly. Send it to anyone β€” no account required to view.

3

Explore in 2D or 3D

Viewers see an interactive map with elevation profile. Switch to 3D mode for a first-person terrain flythrough with playback controls.


Installation

Up and running in minutes

Requires Go 1.21+ and Node.js 16+ to build from source.

bash
# Clone and build
git clone https://github.com/fuzue/share-gpx
cd share-gpx
make build

# Run the server
API_KEY=your-secret-key ./share-gpx

# Open http://localhost:8080 in your browser

Upload via curl
curl -X POST https://your-domain.com/upload \
  -H "X-API-Key: your-secret-key" \
  -F "file=@trail.gpx"

# {"url":"https://your-domain.com/550e8400-e29b-41d4-a716-446655440000"}

Configuration

Environment variables

No config files. Everything is set via environment variables.

Variable Default Description
API_KEY required β€” Secret key for the /upload endpoint. Use openssl rand -hex 32 to generate one.
DATA_DIR /data Directory where GPX files and the SQLite database are stored. Must be writable.
PORT 8080 HTTP listen port.
PUBLIC_URL http://localhost:{PORT} Base URL returned in upload responses. Set this to your public domain.

Tech Stack

Built on solid foundations

Carefully chosen dependencies that stay out of your way.

Backend
Go β€” single binary, fast startup chi β€” lightweight HTTP router modernc/sqlite β€” pure Go, no CGo go:embed β€” frontend bundled in binary
Frontend
Vite β€” fast bundler Leaflet β€” 2D maps MapLibre GL JS β€” 3D WebGL terrain Chart.js β€” elevation profile
Storage
SQLite β€” trail metadata Filesystem β€” raw GPX files
Map Tiles
OpenStreetMap β€” 2D base map ESRI Satellite β€” aerial imagery AWS Terrain β€” elevation data

Ready to share your trails?

Self-host in minutes. MIT licensed. No sign-up required.