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, anduser.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.