Skip to content

GPX Route Manager PWA – Import, dedupe & visualize GPX routes; offline-first, Docker-ready, Next.js + TypeScript.

License

Notifications You must be signed in to change notification settings

TimInTech/gpx-pwa

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

UK flag English | DE flag Deutsch

GPX Route Manager PWA

A lightweight PWA to import multiple GPX files (e.g. from bike computers or exports from Komoot/Strava), deduplicate identical routes, and visualize/manage them on an interactive map. Routes can be toggled, color-coded, and sorted.

Map view Import view

Tech stack icons

Features

  • Import multiple GPX files; merge identical tracks (dedupe)
  • Per-route visibility, color, sort, and basic stats
  • PWA: installable, offline fallback, tile caching (OSM)
  • Fast parsing in a Web Worker (fast-xml-parser)
  • Persistent client storage (IndexedDB/OPFS) with export/import

Tech & Layout

  • Next.js 14 “app/” with standalone output for Docker/runtime
  • Service Worker served from /api/sw with offline fallback & OSM tile cache
  • Worker bundle generated to public/parse.worker.js (predev/prebuild)

Requirements

  • Node.js ≥ 20
  • npm or pnpm

Quickstart (Local)

# install
npm install         # or: pnpm install

# dev (Next.js)
npm run dev

# if the default port is busy:
PORT=3001 npm run dev

# production build + start
npm run build
npm run start
# or change the port:
PORT=3001 npm run start

(Re)build the GPX parser worker manually (normally auto via pre* scripts)

npx esbuild lib/gpx/parse.worker.ts --bundle --format=esm --outfile=public/parse.worker.js --platform=browser

Docker

Build & run

# build multi-stage image
docker build -t gpx-pwa:latest .

# run container on host port 3000
docker run --rm -p 3000:3000 --name gpx-pwa gpx-pwa:latest

Docker Compose

services:
  gpx-pwa:
    build: .
    image: gpx-pwa:latest
    container_name: gpx-pwa
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - PORT=3000
      - HOSTNAME=0.0.0.0
    read_only: true
    tmpfs:
      - /tmp
    security_opt:
      - no-new-privileges:true
    restart: unless-stopped

Start via:

docker compose up --build

PWA/Offline

The SW at /api/sw installs an app cache, an OSM tiles cache (tile.openstreetmap.org, stale-while-revalidate), and a navigation fallback to /offline.html. Next internals (/_next) and /api are excluded.

Testing

  • Unit tests (Vitest) & E2E (Playwright): npm run test, npm run e2e.

Troubleshooting

  • Port in use / EADDRINUSE: try another port (PORT=3001) or stop the other process.
  • Container name in use: docker rm -f gpx-pwa or use a different --name.
  • Healthcheck fails: check http://127.0.0.1:3000/ inside the container.