You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A self-hosted, real-time collaborative travel planner — with maps, budgets, packing lists, a journal, and AI built in.
What you get
See all features
Most of what follows is an addon an admin switches on or off. Lists, Costs, Documents, Collab, Vacay and Atlas ship on; Journey, Collections, MCP, AI Parsing and AirTrail ship off and are marked below.
🧭 Planning
Day plans: drag places between days and reorder inside a day, with undo. Notes and bookings drag the same way, and a map marker drops straight onto a day
Maps: Leaflet, Mapbox GL or MapLibre GL (OpenFreeMap, no token), with clustering, photo markers and route lines. 3D buildings and terrain are Mapbox only
Place search: Google Places when a key is set (photos, ratings, opening hours), otherwise OpenStreetMap with no key
Place enrichment: descriptions, facts, hours and photo candidates from OpenStreetMap, Wikipedia, Wikidata and Wikimedia Commons
POI explore: pull OpenStreetMap POIs by category for the current viewport over Overpass
Import: shared Google Maps and Naver Maps lists, plus GPX, KML and KMZ files
Export: GPX of a trip's places and tracks, and an ICS feed per trip or across all of them
Routes: auto-sort a day (nearest neighbour then 2-opt, locked stops and hotel anchors stay put), driving, walking or cycling profiles over OSRM, then open it in Google Maps or CoMaps
Public transport: door-to-door itineraries over Transitous
Weather: 16-day forecast from Open-Meteo, no key. Dates outside that window read the archive for the same date instead
Day notes: markdown body with an icon and a colour, reordered by drag and drop or moved to another day
Trip dates: move a trip and the days re-date themselves, either dragging the bookings along or re-anchoring them. Trips also copy and archive
🧳 Bookings and money
Reservations: 16 booking types with status, confirmation code, travellers and attached files
Flights and trains: several legs with stopovers, per-leg times and endpoint timezones, against 4,045 bundled airports so local times resolve without a key
Accommodation: a stay spans a range of days with a check-in window, and shows on every night it covers
Booking import: EML, PDF, PKPass, HTML and TXT confirmations through KItinerary. Needs the kitinerary-extractor binary, which ships in the Docker image
AirTrail (off by default): link a self-hosted AirTrail instance to import flights as reservations and keep them in sync
Costs: split expenses in integer cents with equal or custom shares, several payers per expense, settle-up suggestions, a settlement log, and CSV export
Currencies: a currency per expense with the rate frozen at entry. Rates come from Frankfurter, no key
Packing lists: categories, admin-managed templates, assignees, three visibility tiers, and a packed-of-total line. Bags with weight roll-up are a separate admin switch, off by default
To-dos: assignee, due date, priority, and a reminder before one falls due
Files: attach to a trip, place, day entry or reservation. 50 MB each, 500 MB for video, with trash and restore
PDF export: cover page, place photos, day notes, bookings and costs, with an optional page break per day
👥 Collaboration
Real-time sync (WebSocket): edits land live for everyone who has that trip open
Members: add by email or username, hand ownership to someone else, or add guests who have no login at all
Permissions: an admin maps each of 16 trip actions to admin, trip owner, trip member or everybody
Invite links: one reusable link per trip with an optional expiry. Admins can also issue signup invites with a use limit that drop the new account straight into a trip
Public share: a read-only trip page anyone can open without an account
Collab: group chat with replies, reactions and link previews, shared notes with attachments, polls, and a What's Next list of upcoming activities. Each of the four switches on its own
📔 Journal, Atlas and Vacay
Journey (off by default): dated entries with story, mood, weather and tags, photos and video from uploads or a linked Immich or Synology Photos library, map views, co-authors, and a public share link
Atlas: mark countries and sub-national regions visited on geoBoundaries outlines, plus a bucket list, travel stats and a consecutive-years-travelled count
Vacay: leave calendar with half days, public holidays from date.nager.at, school holiday overlays for 16 European countries, carry-over between years, and joint or read-only sharing of a plan
Collections (off by default): a place library outside any trip, with labels, ratings, a custom image per place, copy-into-a-trip, and sharing by invite
🧩 Plugins
Third-party plugins: install from the TREK registry or sideload a zip, switch on per instance, with their own pages under /plugins/<id>
Sandboxed: one child process per plugin, 63 grantable permissions, an admin-edited outbound host allowlist, memory and RPC caps, and daily caps on AI and notification calls
Trust: registry downloads are pinned by sha256 and checked against the author's minisign key. A sideloaded zip is marked unverified, and TREK_PLUGINS_ENABLED=false turns the whole system off
Extension points: map markers and layers, place details, day schedules, PDF sections, Atlas layers, journal rows, trip warnings, calendar sources, route profiles and notification channels. Plugin pages run in an opaque-origin iframe
SDK: trek-plugin-sdk on npm, with a manifest validator, a mock host, and a dev-link mode that runs a local build against real data
🤖 AI and MCP
MCP server (off by default): OAuth 2.1 with mandatory PKCE and dynamic client registration. 199 tools, 30 resources, 4 prompts
Scopes: 29 scopes in 14 groups, each one tickable on the consent screen. Tokens are bound to the /mcp resource, and every tool call lands in the audit log
Reach: create trips and days, edit places, packing lists, to-dos, costs, reservations, collections and journeys, mark countries visited, all inside the scopes the token holds
Prompts: trip-summary, plus packing-list and budget-overview when those addons are on
Addon-aware: seven addon gates decide which tools and resources a session sees. Flipping one drops live sessions so the surface re-registers
Booking extraction (off by default): read a confirmation with a local Ollama server, any OpenAI-compatible endpoint, or Anthropic, configured instance-wide or per user
📱 Mobile and offline
Installable: iOS and Android straight from the browser, no App Store. Runs standalone without browser chrome, with the status bar tinted per theme
Phone layouts: a separate shell below 768px with its own tokens, a bottom bar and safe-area insets. Which items sit in that bar is up to the user
Offline reads: the app shell and every route chunk are precached, and trips, places and file blobs live in a per-user IndexedDB store, so a trip opens with no network
Offline writes: mutations queue and replay with an X-Idempotency-Key, so a reconnect cannot double-apply. A stale edit is parked for a keep-mine or keep-theirs choice
Offline maps: pre-download a trip's raster tiles, and clear them again
API responses are never cached by the service worker. They vary per session, so they always come from the network
⚙️ Admin, accounts and security
Login methods: password login, password registration, OIDC login, OIDC registration and passkey login each switch on and off on their own. OIDC_ONLY leaves SSO as the only way in
SSO (OIDC): one provider by discovery, with PKCE and id_token verification (Authentik, Keycloak, Google and the like)
2FA: TOTP with ten single-use backup codes, and an admin can require it instance-wide
Passkeys: WebAuthn login by fingerprint, face, PIN or security key, off until an admin enables it. A passkey also satisfies the 2FA requirement
Hardening: per-IP limits on login, password reset and 2FA attempts, a password policy, secrets encrypted at rest and masked on read, and an SSRF guard on every URL you configure
Admin panel: users and invites, the permission matrix, packing templates, categories, addons, plugins, API keys, MCP tokens and OAuth sessions, backups, storage, audit log, and GitHub releases
Backups: manual or scheduled hourly, daily, weekly or monthly, with retention in days. The zip carries the at-rest key, so a restore can decrypt its own secrets
Storage: pluggable storage backends per content category — keep everything on local disk, or add S3-compatible backends and replicate any category to them, configured entirely from the admin panel
Notifications: a per-user matrix of events against in-app, email (SMTP), webhook and ntfy, plus any channel a plugin registers
Appearance: light, dark or follow the OS, seven colour schemes plus a custom accent, transparency, compact density, reduce motion, and text size per tier
23 languages: en, de, es, fr, it, nl, hu, ru, zh, zh-TW, pl, cs, ar (right to left), br, id, tr, ja, ko, uk, gr, sv, vi, ca
In-app help: the wiki ships inside the image and is served from disk at /help, so the docs match the version you are running
AI usage
We use LLM-assisted coding tools across parts of this codebase. Nothing ships that a
maintainer has not read and understood: every change goes through a pull request, is
reviewed and tested, and has a human who can answer for it. "The AI wrote that" is not
an answer any of us would accept from ourselves.
Open http://localhost:3000. On first boot TREK seeds an admin account — if you set ADMIN_EMAIL/ADMIN_PASSWORD those are used, otherwise the credentials are printed to the container log (docker logs trek).
Real-time sync via WebSocket (ws). Backend on NestJS 11. State with Zustand. Auth via JWT + OAuth 2.1 + OIDC + Passkeys (WebAuthn) + TOTP MFA. Weather via Open-Meteo (no key required). Maps with Leaflet and Mapbox GL.
Docker Compose (production)
The repository ships a ready-to-use docker-compose.yml
with secure defaults and every option documented inline. Download it, then:
TREK works as a Progressive Web App — no App Store needed.
Open TREK in the browser (HTTPS required)
iOS: Share ▸ Add to Home Screen
Android: Menu ▸ Install app (or Add to Home Screen)
TREK then launches fullscreen with its own icon, just like a native app.
Updating
See Updating — Docker Compose,
Docker run, Helm, Portainer, Unraid and Proxmox, plus the encryption-key note.
Reverse Proxy
For production, put TREK behind a TLS-terminating reverse proxy. TREK uses WebSockets for real-time sync, so the proxy must support WebSocket upgrades on /ws.
If you use the MCP addon, the proxy must also pass the Mcp-Session-Id header through in both directions on /mcp — Nginx and Caddy do this by default, but a proxy that strips it makes every tool call open a new session instead of reusing one. See the Reverse Proxy wiki page for details.
Nginx
server{listen80;server_name trek.yourdomain.com;return301 https://$host$request_uri;}server{listen443ssl http2;server_name trek.yourdomain.com;ssl_certificate /etc/ssl/fullchain.pem;ssl_certificate_key /etc/ssl/privkey.pem; # 500 MB covers backup-restore uploads (capped at 500 MB server-side).client_max_body_size500m;location / {proxy_passhttp://localhost:3000;proxy_http_version 1.1;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;}location /ws {proxy_passhttp://localhost:3000;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";proxy_set_header Host $host;proxy_read_timeout86400;} # Only needed if you use the MCP addon. Responses are Server-Sent Events, # so buffering must be off or tool results arrive late.location /mcp {proxy_passhttp://localhost:3000;proxy_http_version 1.1;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;proxy_buffering off;proxy_read_timeout3600s;}}
The Atlas map's country and sub-national (province/county) boundaries come from
geoBoundaries (Runfola et al., 2020), licensed
CC BY 4.0. See NOTICE.md
for full third-party attributions.
License
TREK is AGPL v3. Self-host freely for personal or internal company use. If you modify and offer TREK as a network service to third parties, your modifications must be open-sourced under the same licence.
About
A self-hosted travel/trip planner with real-time collaboration, interactive maps, PWA support, SSO, budgets, packing lists, and more.