Overview
Planning a trip with other people usually means juggling a group chat, a spreadsheet, a maps app, booking emails, and a notes app for packing. Nothing ties it all to the same day-by-day plan, and generic AI chatbots suggest places without knowing what's already on the itinerary.
Voyager is a collaborative trip-planning web app, responsive for mobile, that puts the whole trip on one timeline. Every day shows up, including empty ones, and stays, events, transport, tasks, comments, photos, and journal entries all hang off it. An AI travel assistant reads that timeline directly.
I built it in June and July 2026, and it's deployed on Railway.
What it does
Trip timeline
- Day-by-day plan with collapsible days
- Straight-line distance between events
- Daily weather forecast for the trip
AI travel assistant
- Suggestions based on the actual itinerary and real Google Places results
- Place cards with photos
- Save any suggestion to the trip's Maybe list
Maps and places
- Map pins for events, stays, and Maybe-list places, with filters and fullscreen
- Events with address, website, and a navigate button
Transport and costs
- Transport in 10 modes, each with payment status and amount paid
- Flight lookup
- Trip-wide cost summary
Planning together
- Comments on every item
- Tasks with assignment, progress, and checklists, plus per-user packing lists
- Read-only shareable presentation page for a trip
Photos and journal
- Photo uploads with thumbnails and a lightbox
- Daily journal entries with photos, shown on the timeline
How it's built
An assistant grounded in the trip
A plain chatbot recommends places with no awareness of the itinerary, and can name places that don't exist. Voyager runs Claude Sonnet in an agent loop with seven tools to read the trip's info, events, stays, transport, and costs, and to search and look up places through Google Places. That way suggestions come from the trip as it actually stands and from places that exist.
No framework on the front end
The client is vanilla HTML, CSS, and JavaScript, responsive for planning on a phone, with the Google Maps JavaScript API for the map.
A modular Express API
A Node.js and Express API is split into 16 route modules, one per area of the product, over an 18-table PostgreSQL schema that's created automatically on startup. Flight results from AviationStack are cached in Postgres and Open-Meteo forecasts for six hours, to keep third-party calls down.
Moving photos out of the database
Photos were originally stored as base64 in Postgres. I migrated them to Cloudflare R2 and kept a read fallback so photos still stored the old way keep loading.
Passwordless sign-in
Sign-in uses magic links sent by Resend, with sessions stored in the database, so there are no passwords to store or reset. The API is covered by BDD-style HTTP tests in Jest and Supertest.