The Problem

Trail data lives scattered across GPS devices, Strava, Komoot, and Hammerhead accounts. wanderer solves that by giving you a self-hosted catalogue where recorded tracks become searchable, shareable entries with metadata, maps, and ActivityPub federation—so your adventure data isn't locked in a proprietary platform.

What This Does

wanderer is a full-stack trail database. The web/ directory holds a SvelteKit frontend with map visualization, search, and trail management. The db/ directory is a Go backend that handles persistence, ActivityPub federation, and third-party integrations.

Key integrations in db/integrations/ sync trails from Strava, Komoot, and Hammerhead. The db/federation/ package implements ActivityPub, letting instances share trails and follow users across servers. The db/ backend also manages a Meilisearch index for fast search, with migrations in db/migrations/ tracking schema changes.

How It Is Wired

Execution starts at main in db/main.go:58, which reaches 41 functions. From there, setupEventHandlers (line 89) wires 35 functions into the event system, and registerRoutes (line 160) sets up the HTTP API. The backend uses a Postgres database (evidenced by the extensive migration history) and Meilisearch for search indexing, initialized via initMeilisearchDocuments (line 359).

The highest-fan-in functions are the federation and notification core: PostActivity (called from 14 places), GetSafeActorContext (11), SafeHTTPClient (9), and SendNotification (7). These sit in db/federation/activity.go and db/util/network.go — change any of them and you break most of the integration and federation paths.

The third-party sync flow runs through syncTrailWithTours, which calls FindTrailByExternalReference, fetchDetailedTour, generateTourGPX, createTrailFromTour, and TryAutoMergeImportedTrail — each called twice from that single function. db/services/trailmerge/service.go owns the merge logic with 51 functions, making it the largest service file. The db/util/network.go file performs cryptographic operations (key generation for ActivityPub) and is imported by 10 other files.

The module graph shows two import cycles: web/src/lib/models/trail.ts, activitypub/actor.ts, and user.ts are mutually reachable. That costs you when refactoring — changing a type in one ripples through the others, and the cycle prevents clean modular extraction.

How To Use It

Setup: Docker Compose is the recommended path, per the README:

wget https://raw.githubusercontent.com/open-wanderer/wanderer/main/docker-compose.yml
docker compose up -d

Configuration: Set ORIGIN to your hostname (defaults to localhost:3000) to avoid CORS errors. Set MEILI_MASTER_KEY in production — the README warns the default is insecure. Both go in your environment or the docker-compose.yml.

Running: After startup (up to 90 seconds), the frontend is at localhost:3000. For bare-metal, the docs at docs/ cover building from source.

Real-World Use

A trail-running club runs wanderer on a VPS. Members link their Strava accounts via the integration in db/integrations/strava/strava.go. When someone uploads a GPX, db/services/trailmerge/service.go deduplicates it against existing trails and offers a merge suggestion. The club's instance federates with another club's server via ActivityPub, so shared trails appear in both catalogs through db/federation/activity.go.

Code Health & Issues

Static analysis found 117 findings: 54 high, 63 medium. The high-severity items are:

  • High – Import cycles in web/src/lib/models/trail.ts, activitypub/actor.ts, and user.ts — mutually reachable modules make refactoring risky.
  • High – Oversized files: web/src/lib/util/icon_util.ts (1528 lines), db/services/trailmerge/service.go, web/src/routes/trail/edit/[id]/+page.svelte.
  • High – Deep nesting (depth 10) in geojson_util.ts, combobox.svelte, editor.svelte.
  • High – Duplicated code blocks: 737 repeated 6-line blocks across 201 files, concentrated in db/federation/.

SDLC observations: CI uses GitHub Actions, tests exist but cover only 8 of 590 source files (ratio 0.014). The code health audit flags unpinned GitHub Actions tags (@v4, @v8), missing permissions declarations on the workflow token, an unpinned base image in db/Dockerfile, no dependency vulnerability scan, large binaries committed (10.6MB trailer.mp4), and a root user in the Docker image.

The Bottom Line

wanderer is a functional, feature-rich trail database with real federation and third-party integrations — the architecture is sound and the feature set is impressive. The main risks are maintenance: import cycles, oversized files, and weak test coverage will make changes progressively harder. Use it if you need a self-hosted trail catalogue with federation; budget time for refactoring before deep customization.