TREK: a self-hosted trip planner with real-time collaboration
A self-hosted travel/trip planner with real-time collaboration, interactive maps, PWA support, SSO, budgets, packing lists, and more.
At a glance
- What is it?
- TREK is an AGPL-3.0 TypeScript travel planner you run yourself, with WebSocket collaboration, Leaflet/Mapbox maps, budgets in integer cents and a sandboxed plugin system. The Docker image is the intended path; the plugin runtime and the AI addons are where the sharp edges are.
- Who is it for?
- TREK suits a household, a travel group or a club that already runs Docker and wants itinerary, maps and shared costs on hardware it controls, with real-time editing for everyone on the same trip. It does not suit anyone who wants a managed service with no server to look after, or an organisation whose policy rules out AGPL-3.0 code.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem TREK solves, and who ends up running it
A group trip produces a mess that no single tool holds: a spreadsheet of dates, a chat thread of links, screenshots of bookings, a shared note of who paid for what, and a map someone made by hand. TREK's answer is one server that owns the trip. The README describes it as a "self-hosted, real-time collaborative travel planner" with maps, budgets, packing lists, a journal and AI built in, and the repository layout backs that up: client, server and shared workspaces, a plugin-sdk directory, and a Dockerfile that builds all three.
The intended operator is not a tourist. It is someone who already runs a Docker host and is willing to own backups, upgrades and an encryption key. In exchange, the trip data sits on their disk rather than a vendor's. The collaboration model is built around that: members are added by email or username, ownership can be handed to someone else, and guests without any login can be attached to a trip. A read-only public share page exists for people who should look but not edit. That is a group-sized feature set, not a solo one.
How the collaboration, permissions and data flow actually fit together
The mechanism the README is clearest about is real-time sync over WebSocket: edits land live for everyone who has that trip open. Around that sits a permission layer where an admin maps each of 16 trip actions to one of four levels (admin, trip owner, trip member, everybody). That is a coarser model than per-object access control, and it is worth reading as a deliberate simplification. If you need one traveller to see the itinerary but not the costs, the 16-action mapping is the only lever, and the README does not claim it goes finer.
Money is handled with more care than most planners. Expenses are split in integer cents with equal or custom shares, several payers can be attached to one expense, and the app produces settle-up suggestions plus a settlement log. Each expense carries its own currency with the rate frozen at entry, with rates from Frankfurter and no API key. Freezing the rate means historical totals do not drift when the currency moves, which is the right call for a settlement record and the wrong one if you wanted live conversion in a report. The README does not describe a recompute-on-demand path.
Maps are pluggable at the provider level: Leaflet, Mapbox GL or MapLibre GL, with OpenFreeMap usable without a token. Place search falls back to OpenStreetMap when no Google Places key is set, and 3D buildings and terrain are Mapbox only. So the no-key configuration is viable, and it is visibly the cheaper configuration in features.
Installing TREK from the Docker image
The repository ships a docker-compose.yml built around the published image `mauriceboe/trek:latest`. The service is hardened by default: the container filesystem is read-only, all capabilities are dropped and only CHOWN, SETUID and SETGID are added back, and /tmp is a tmpfs mounted noexec with a 128 MB cap. The app listens on port 3000, mapped to 3000 on the host.
The one setting worth generating before first boot is the encryption key. The compose file comments give the command and explain the fallback behaviour.
openssl rand -hex 32Put that value in an .env file next to the compose file as ENCRYPTION_KEY and start the stack. According to the compose comments, if ENCRYPTION_KEY is unset the app falls back to data/.jwt_secret on existing installs, or auto-generates a key on a fresh install. Setting it explicitly is the documented recommendation, and it is the difference between a key you can restore and one you cannot.
services:
app:
image: mauriceboe/trek:latest
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- PORT=3000
- ENCRYPTION_KEY=${ENCRYPTION_KEY}
- TZ=Europe/BerlinTwo other environment variables matter for a first real use. TZ controls logs, reminders and scheduled tasks, so a wrong value shifts your to-do reminders. SESSION_DURATION accepts 1h, 12h, 7d, 30d or 90d and defaults to 24h, with SESSION_DURATION_REMEMBER defaulting to 30d for the "Remember me" path. After the container is up, open port 3000, create the admin account, then create a trip and add a second member by email or username. That is the point at which the WebSocket layer becomes observable: open the same trip in two browsers and an edit in one should appear in the other without a refresh.
Where TREK gets awkward: plugins, AI and the booking importer
The plugin system is the most ambitious part of the project and the part with the most caveats. Plugins install from the TREK registry or as a sideloaded zip, run one child process each, and are constrained by 63 grantable permissions, an admin-edited outbound host allowlist, memory and RPC caps, and daily caps on AI and notification calls. 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 disables the whole subsystem. That is a serious sandbox design, but it is also a moving target: the README says most features are addons an admin switches on or off, and the ones shipped off by default (Journey, Collections, MCP, AI Parsing, AirTrail) are exactly the ones with the least documented operational behaviour.
Booking import is the other sharp edge. It handles EML, PDF, PKPass, HTML and TXT confirmations through KItinerary, and it needs the `kitinerary-extractor` binary. The README states that binary ships in the Docker image, so the image is effectively required for that feature; a source build has to supply it. Flight and train legs resolve local times against 4,045 bundled airports without a key, which is a real convenience, but the importer itself is a parsing pipeline over messy real-world documents. Expect to correct entries by hand.
Files are capped at 50 MB each and 500 MB for video, with trash and restore. That is a modest ceiling for a group uploading video from a phone, and the README presents no configurable override.
TREK against Wanderlog and plain shared documents
The honest comparison is with a hosted planner such as Wanderlog. Wanderlog gives you a polished itinerary map and collaboration with no server, no Docker host and no upgrade path to own. TREK gives you the same shape of product on your own hardware, and the trade is explicit: you gain control of the data and the ability to extend it, and you take on a container to patch, a database to back up and an encryption key to keep. If nobody in your group enjoys running a server, the hosted option wins on total effort.
The second alternative is the one most groups actually use: a shared document plus a chat thread plus a spreadsheet. That costs nothing and needs no maintenance, and it fails in specific ways TREK addresses. Drag places between days with undo, auto-sort a day with nearest neighbour then 2-opt while locked stops and hotel anchors stay put, split expenses in integer cents with settle-up suggestions, and keep packing lists with three visibility tiers. Those are the operations a document cannot do well. It is also worth noting what TREK does not replace: it is not a booking engine, and the KItinerary import reads confirmations you already have rather than buying anything.
Licence, maintenance and what an upgrade costs you
TREK is licensed AGPL-3.0. For a self-hosting household that changes nothing. For anyone who wants to modify TREK and offer it to others over a network, the AGPL's source-availability condition is the thing to read before you build on it, and that is a question for your own counsel rather than for this article. The repository also carries a TRADEMARKS.md alongside the LICENSE, which is worth opening if you plan to run a modified instance under a similar name.
The last push to the default branch was on 2026-08-27, the same day as the v4.0.0 release, following two pre-releases in August. The repository is not archived. The root package.json declares version 4.2.1, which does not match the v4.0.0 release tag, so if you pin a version, pin the container image tag rather than reading the manifest.
Upgrade cost is dominated by the encryption key and the database. The compose file's fallback chain (ENCRYPTION_KEY, then data/.jwt_secret, then an auto-generated key) means a fresh install that skipped the key can produce data that a later install cannot read without the same data directory. Back up the data volume and the key together. The Dockerfile is a four-stage build on node:24-alpine and node:24-trixie-slim, and it rebuilds gosu from source with a current Go toolchain to avoid a stale stdlib in the runtime image, so a source build pulls Go as well as Node.
Editorial conclusion
TREK suits a household, a travel group or a club that already runs Docker and wants itinerary, maps and shared costs on hardware it controls, with real-time editing for everyone on the same trip. It does not suit anyone who wants a managed service with no server to look after, or an organisation whose policy rules out AGPL-3.0 code. Before committing, check the plugin runtime and AI addons against your own deployment, because those are the parts the README describes least concretely, and confirm that the mauriceboe/trek image tag you pin still matches the version you evaluated.
Frequently asked questions
What is a good collaborative itinerary planner app?
TREK is one candidate: the README describes real-time sync over WebSocket so edits land live for everyone who has that trip open, plus members added by email or username, ownership transfer, and a read-only public share page. Whether it is good for you depends on whether you are willing to run the Docker image yourself.
Is there an open source itinerary planner available?
TREK is open source under AGPL-3.0 and is published as a self-hosted application, with the container image mauriceboe/trek on Docker Hub and a docker-compose.yml in the repository. The source is TypeScript across client, server and shared workspaces.
How do I install TREK?
The repository ships a docker-compose.yml that runs the mauriceboe/trek:latest image on port 3000 with a read-only filesystem and dropped capabilities. Generate an encryption key with openssl rand -hex 32, set it as ENCRYPTION_KEY, and start the stack.
Does TREK need API keys for maps and weather?
No. Place search falls back to OpenStreetMap when no Google Places key is set, MapLibre GL with OpenFreeMap needs no token, and the 16-day forecast comes from Open-Meteo without a key. Google Places and Mapbox add photos, ratings, opening hours, 3D buildings and terrain when configured.
How does TREK split trip costs?
Expenses are split in integer cents with equal or custom shares, and several payers can be attached to one expense. Each expense carries its own currency with the rate frozen at entry, with rates from Frankfurter, and the app produces settle-up suggestions and a settlement log.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/liketrek-trek)