DEV Community

Dubaguntla Charan Sai
Dubaguntla Charan Sai

Posted on

Building a Trip Planner with Vanilla JS and JSON: How I Structured Travel Sync's Data

Not every project needs a database and a backend framework. When I built Travel Sync, a trip planning and itinerary management web app, I used plain HTML, CSS, and JavaScript with JSON for data — no backend, no build tools. Here's how I structured the data so the app stayed manageable as features grew, and what I'd suggest if you're building something similar.

The Stack

  • Frontend: HTML, CSS, JavaScript (no framework)
  • Data: JSON, structured and persisted client-side
  • Deployment: Render, with version control on GitHub

Step 1: Model Your Data Before Writing UI Code

The core challenge in a trip planner is nesting: a trip has multiple destinations, each destination has multiple days, and each day has multiple activities. It's tempting to just start building forms and figure out storage later — don't. I started by writing out the shape of the data first:

{
  "tripId": "t1",
  "tripName": "Goa Weekend",
  "destinations": [
    {
      "name": "Goa",
      "days": [
        {
          "date": "2026-09-12",
          "activities": [
            { "time": "09:00", "title": "Beach visit", "notes": "Bring sunscreen" }
          ]
        }
      ]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Lesson: once you know the nesting, the UI components almost design themselves — a trip list, a destination view, a day view, an activity list. Data shape drives component shape.

Step 2: Keep One Source of Truth

Early versions of Travel Sync had trip data scattered across multiple JS variables that got out of sync — editing an activity in one place didn't update the summary view elsewhere. The fix was boring but important: one JSON object in memory as the single source of truth, with every UI update reading from and writing back to it.

let tripData = loadTripsFromStorage();

function updateActivity(tripId, dayIndex, activityIndex, newActivity) {
  const trip = tripData.find(t => t.tripId === tripId);
  trip.destinations[0].days[dayIndex].activities[activityIndex] = newActivity;
  saveTripsToStorage(tripData);
  renderTrip(tripId);
}
Enter fullscreen mode Exit fullscreen mode

Lesson: in any app without a backend, decide early where the "truth" lives, and make every function read/write through it instead of touching the DOM directly.

Step 3: Re-render Instead of Patching the DOM by Hand

Without a framework, it's tempting to manually update individual DOM elements when data changes. This gets unmanageable fast once you have nested lists (trips → destinations → days → activities). Instead, I rendered each section from the current data state every time something changed:

function renderTrip(tripId) {
  const trip = tripData.find(t => t.tripId === tripId);
  const container = document.getElementById("trip-view");
  container.innerHTML = trip.destinations
    .map(d => renderDestination(d))
    .join("");
}
Enter fullscreen mode Exit fullscreen mode

It's less "efficient" than surgical DOM updates, but for an app this size, it's far easier to reason about — the UI always matches the data because it's rebuilt from the data.

Lesson: for small-to-medium apps, "re-render the whole section from data" beats hand-patching the DOM. Optimize only if you actually hit a performance problem.

Step 4: Design Mobile-First from the Start

Since people plan trips on their phones as much as on desktops, I built the layout mobile-first — single-column day views, collapsible destination sections — then expanded the CSS for larger screens rather than the reverse. Retrofitting mobile support onto a desktop-first layout is almost always more painful than starting mobile-first.

What I'd Tell Someone Starting This Today

  1. Model your nested data structure before writing any UI.
  2. Keep a single source of truth and update everything through it.
  3. Re-render from data instead of manually patching the DOM.
  4. Build mobile-first, especially for anything travel-related.

You don't need a framework or a backend to build something real — you just need a clear data model and some discipline about where state lives.


Travel Sync is a trip planning and itinerary management web app built with HTML, CSS, JavaScript, and JSON. Live demo here.

Top comments (0)