TravelMap: A Self-Hosted Travel Diary That Turns Messy Trips Into a Living Map
A vanilla PHP project with a surprisingly sophisticated map stack, automated importers, and offline-aware design, built for people who want control over their travel history.
- TravelMap’s real product is the ingestion layer, because it turns photos, flights, and bookings into one durable travel record.
- The project uses vanilla PHP as a deployment strategy, not a compromise, so it can run cleanly on modest hosting without a heavy framework.
- Its dual map stack lets the same trip data serve both broad compatibility and high-end visuals.
- Offline tile caching makes sense here because travel often happens where connectivity is weakest.
The real product is not the map
TravelMap looks like a travel journal on a map, but that is the surface layer. The interesting part is the machinery underneath: it can take photos with GPS metadata, flight exports, Airbnb bookings, and manual edits, then reconcile them into one private travel story on your own server.
That matters because most travel memories are already fragmented. They live in camera rolls, booking emails, airline receipts, and a few saved pins. TravelMap’s bet is that the hard part is not pinning locations. It is compiling the evidence into something coherent and portable.
How TravelMap turns fragments into a trip story
The importer pipeline is the project’s most distinctive idea. Photos become location-tagged moments. Flight data becomes routes and transit events. Airbnb exports become stay points. Manual edits fill in the gaps where the data trail ends.
Why vanilla PHP is part of the point
The stack is not flashy, and that is the point. The repo leans on plain PHP, a model layer, API endpoints, migrations, and a settings table instead of a framework-heavy setup. That makes it easier to deploy, easier to move, and less dependent on a modern build pipeline staying intact.
// The architecture pattern is straightforward on purpose.
$settings = Settings::getAll();
$renderer = $settings['map_renderer'] ?? 'leaflet';
$data = Api::getAllTravelData();
if ($renderer === 'maplibre') {
MapRenderer::renderVectorMap($data);
} else {
MapRenderer::renderLeafletMap($data);
}
That simplicity does not mean the project is thin. It still has enough structure to support migrations, importers, user settings, and a consistent travel model. The result is a system that feels lightweight to host but serious in what it can absorb.
Two map engines, one experience
| Layer | Leaflet | MapLibre plus deck.gl |
|---|---|---|
| Best fit | Broad compatibility and lower-end devices | High-performance vector rendering and animated overlays |
| Strength | Reliable, familiar, easy to run | More polished, more visual, better for complex arcs and layers |
| Trade-off | Less dramatic visual depth | Heavier stack, more demanding on the client |
| What stays the same | The same canonical trip data | The same canonical trip data |
TravelMap does not force a false choice between usability and visual ambition. Leaflet handles the practical baseline. MapLibre and deck.gl step in when the app wants to feel like a modern travel product instead of a simple pinboard.
The offline layer is the quiet superpower
The offline story is easy to miss, but it is one of the smartest parts of the design. Travel does not happen in ideal network conditions. Airports, trains, remote towns, and weak hotel Wi-Fi are exactly where a map diary becomes most useful.
The service worker tile caching means the map can remain useful when connectivity falls apart. That aligns the software with the user’s reality instead of assuming the user is always online, always synced, and always patient.
What it is better than, and what it is not
| Alternative | Where it wins | Where TravelMap wins |
|---|---|---|
| Social travel platforms | Network effects and public storytelling | Privacy, ownership, and automatic import |
| Generic map plugins | Simplicity and fast setup | A richer import pipeline and a stronger travel model |
| Mainstream map apps | Frictionless everyday use | Self-hosting, portability, and better narrative reconstruction |
This is not trying to be a better Instagram feed or a prettier Google Maps list. It is trying to become a durable archive for trips you already took. That makes it less of a consumer app and more of a personal infrastructure layer.
The project’s hidden bet
TravelMap assumes something subtle but important: people want their travel history to survive platform churn. That is why the app matters. It treats memory as data integration, not content creation, and that is a stronger idea than it first sounds.





