An interactive virtual passport built from my TripIt flight history. Static site, hand-built in vanilla HTML/CSS/JS + D3 for the maps.
Live site: https://mbriney.github.io/Travel/
A passport-style book you can page through:
- Cover — embossed passport cover
- Bearer page — name, residence, headline stats
- Flight stats — Flighty-style cards: weekday histogram, distance factoids (Earth laps, Moon trips), top airports / airlines / routes, shortest & longest flights
- World map — countries shaded by visits, great-circle arcs for routes, dots for visited airports
- United States — choropleth of visited states with abbreviation labels
- Stamp pages — one customs-style stamp per visited country, with arrival/departure dates and the airports visited there
- Flight log — full reverse-chronological log of every flight
Navigation: click left/right halves of the passport, use ← / → arrow keys, the page-jump pills in the header, or swipe on mobile.
.
├── index.html # site entry point
├── assets/
│ ├── css/passport.css # all styling (passport, flips, maps, stamps)
│ └── js/ # ES modules
│ ├── main.js # boot — load JSON, build pages
│ ├── stats.js # aggregate flight stats from the raw list
│ ├── pages.js # build each passport page
│ ├── passport.js # flip-book navigation
│ ├── worldmap.js # D3 world map with arcs
│ └── usmap.js # D3 US states map
├── data/ # the data the site reads at runtime
│ ├── flights.json # one entry per flight segment (from TripIt)
│ ├── airports.json # IATA -> { lat, lon, name, country, state }
│ ├── airlines.json # IATA -> { name, country }
│ └── countries.json # ISO2 -> { name, continent }
└── tools/ # Python pipeline scripts
├── build_airports.py # one-time: download airport / airline DB
├── fetch_tripit.py # OAuth + paginated trip fetch -> flights.json
├── make_sample.py # generate demo data (used when no TripIt data yet)
└── requirements.txt
# One-time setup (only needs to be run again to refresh the airport DB)
python3 -m pip install -r tools/requirements.txt
python3 tools/build_airports.py
# Configure TripIt credentials (one-time)
cp tools/credentials.example.json tools/credentials.json
# edit tools/credentials.json and paste your consumer_key + consumer_secret
# Fetch your flights (first run opens browser for OAuth approval)
python3 tools/fetch_tripit.pyAfter that, just rerun python3 tools/fetch_tripit.py whenever you want a fresh snapshot.
TripIt only gives you a short aircraft type code (e.g. 738). If you want
the actual tail number that flew each route — plus aircraft model, ATC
callsign, and Mode-S transponder hex — run the AeroDataBox enrichment
script:
python3 tools/enrich_aerodatabox.py # incremental
python3 tools/enrich_aerodatabox.py --dry-run # show what would be fetched
python3 tools/enrich_aerodatabox.py --limit 50 # cap a single run- Grab a free RapidAPI key at https://rapidapi.com/aedbx-aedbx/api/aerodatabox (Free tier: 600 requests/month, ~last 365 days only).
- Add it to
tools/credentials.json:{ "aerodatabox_rapidapi_key": "YOUR_RAPIDAPI_KEY_HERE" } - Run the script. It rate-limits to 1 req/sec and caches every response under
data/_aerodatabox_cache/so re-runs are free against your quota.
Coverage: AeroDataBox's historical window is roughly the last 365 days. Older flights can't be enriched from any public API. After running, the Stats tab grows a "Specific aircraft" card showing your most-flown tails, and each flight's detail modal shows its registration.
The fetcher uses OAuth 1.0a. You'll need:
consumer_key— your TripIt API ID from the developer consoleconsumer_secret— your TripIt API Secret
The script opens your browser for a one-time approval, then stores the access token + secret back into tools/credentials.json (which is gitignored). All subsequent fetches are silent.
This repo is set up to serve the site from the root via GitHub Pages.
- Push the repo to GitHub.
- Settings → Pages → Source: Deploy from a branch → branch
main(ormaster), folder/ (root). - Your site will be live at
https://<username>.github.io/Travel/.
No build step. The pre-baked data/*.json files are the entire payload.
cd Travel
python3 -m http.server 8080
# open http://localhost:8080A static server is required because the page loads JSON via fetch() — opening index.html from file:// will be blocked by the browser.
- Map data: world-atlas, us-atlas
- Airport / airline data: OurAirports, OpenFlights
- Visual inspiration: the Flighty annual passport screenshots and TravStats