Get in touch
All work

Case study · Travel

Passport Pin

The travel app that closes the loop. Track where you have been, save where you are going, turn it into a real trip, book it, and start again.

Solo build. Web and mobile, one codebase philosophy, one backend. Researched, designed, built and shipped by me.

Client
Personal project
Role
Research, design, engineering and content. Everything.
  • Next.js
  • Expo
  • React Native
  • Supabase
  • Edge functions

It always starts the same way

It is a Tuesday night. I have got two weeks off in April and a blank Google Doc open, called “Singapore??”

I have wanted to go for some time, and I have been quietly saving places the whole while. A friend’s story here, a reel at midnight there, a blog post half read on a train.

And here I am, typing “Day 1” into an empty page like none of it ever happened.

That was the moment I realised there has to be a better way. Not a gap in a market. Just a slightly annoying evening that kept repeating.

Three things that bothered me every trip

Once I noticed it, I could not stop.

  1. My bucket list went nowhere. Saving a place and going to a place were disconnected acts. Hundreds of the first, a handful of the second, nothing in between.

  2. Every trip started from scratch. Years of accumulated intent, and the tools still handed me an empty box.

  3. One trip, six apps. A tracker for the map, a planner for the itinerary, a converter for the currency, fourteen browser tabs for the booking. None of them knew about each other, or anything about me.

Then I went looking at what already existed, and the market had the same shape as my phone. The trackers were beautiful and did nothing with what you gave them. The planners were powerful and started every trip as a stranger. So the most obvious feature in travel software, use what I already told you, existed nowhere.

Screen to come

Six separate apps on one side, one repeating loop on the other

The fragmented before, against the single after loop

Passport Pin is one idea, repeated.

Track

Pin the countries, regions, cities and landmarks you have already been to.

Track → Pin → Plan → Book → Track again

  1. Track. Pin the countries, regions, cities and landmarks you have already been to.
  2. Pin. Save where you want to go next, in exactly the same map.
  3. Plan. Nine pins in Japan becomes a day by day itinerary in one tap.
  4. Book. Stays, tours and transport attach to every stop, then the map fills in again.

The loop

You pin the countries you have been to and the map fills in. Not just countries, but regions, cities, landmarks and UNESCO sites, so it keeps rewarding you the closer you look. Places you want to go are saved the same way, in the same map.

Then it watches for a cluster. Nine pins in Japan is not a wishlist any more, it is a trip waiting to happen, and the app says so. One tap turns those pins into a day by day itinerary, with stays, tours and transport attached to every stop.

You go. You come home. It asks whether you made it to the fourteen places you planned, and the map fills in further.

That last screen is the entire product. It is the moment tracking stops being a novelty and becomes a reason to plan the next one, and it is why this is a loop instead of a funnel.

Screen to come

Nine pins in Japan, and the prompt offering to make them a trip

Screen to come

The itinerary that prompt generates, day by day

The cluster prompt, and the itinerary it generates

What it turned into

Five sections. Map is your travel identity: stats, completion percentages, badges, a yearly Wrapped built to be shared. Pins is the wishlist, including pasting in a social post and letting the app pull the places out of it. Trips is the itinerary builder, AI assisted with an offline fallback so it can never dead end. Explore is the destination layer. Tools is the unglamorous stuff you open daily abroad: currency, phrasebook, packing, time zones.

Underneath it is a collector economy rather than a streak. Rarity tiers, levels, badges, completion percentages. Travel is not a daily habit, so nothing punishes you for the eleven months between trips.

Screen to come

The stats screen: countries, cities and days away

Screen to come

A badge unlocking the moment a visit is logged

The identity layer: stats, and a badge unlock

Building it

I built it solo, with AI coding assistants doing the typing while I did the deciding. That is not a footnote, it is the reason a marketer shipped a real product instead of a deck about one.

It runs in two places for two different reasons. The web app, in Next.js, is where planning happens: a big screen, a map beside an itinerary, a shareable URL so a trip card travels further than an app store ever will. The mobile app, in Expo and React Native, is where travelling happens: pinning a place while standing in front of it, and an itinerary that still opens with no signal.

Keeping both honest meant putting almost nothing in either. Supabase holds the data, the auth and the row level security. Edge functions hold every API key and partner call. The content catalogue and the types are shared, so a country page is written once and rendered twice. Two front ends over one truth, not two products.

But the interesting problem was never the interface. It was the data.

“Show every country, region, city and landmark on earth” sounds like a content task and is really a pipeline question, so I split every fact into four tiers, each with its own rules.

  1. The world skeleton, geometry and cities and coordinates and plug types, comes from open data (Natural Earth, GeoNames, Wikidata, OurAirports, UNESCO) and is baked in at build time, so the map still works at 38,000 feet.

  2. The editorial layer, the blurbs and best months and cost bands, is generated offline from those sourced facts, validated in code against a ban list, and spot reviewed by hand. Never at runtime, so no two users ever see a different version of the same fact.

  3. Live commerce, hotel rates and tour availability and fares, sits behind edge function proxies with short cache windows, because partner terms forbid holding onto it and because that is where affiliate attribution lives.

  4. And regulated data, visas and entry rules, is sourced properly or not shown at all.

One rule holds all four together: every fact on screen carries a source and a checked on date, or it does not go on screen. When a source goes stale the interface degrades to a link out, never to a plausible looking number. It is why “best months to visit” is computed from thirty years of climate normals rather than typed in by hand, and why the visa screen sends you to your government and the database the airline actually checks instead of guessing about your border.

The business runs the same way round. Affiliate commission from the first user, because that needs no inventory, no payments and no support desk. A subscription second, priced against the tools, while the map and the pins stay free forever, because the free half is the half people share.

Screen to come

The four tier model: countries, regions, cities, places

Countries, regions, cities and places, plus visits, pins, trips, days and stops

What I took from it

I started this as a marketer with an annoying Tuesday night and a blank Google Doc. I finished it having designed a schema, built a content pipeline, wired up a dozen third party APIs, and made real calls about data licensing, provenance and liability.

The most useful thing I learned was not technical. It was that the hard part of building a product is deciding what not to build, and that one clear sentence, connect where you have been to where you are going, makes almost every one of those cuts obvious.

Screen to come

The end of trip screen, with the map filled in

The end of trip screen, where the map fills in