joe / sukar
All projects

FlightDetector

When flight data disagrees.

A live flight-tracking interface built around a harder problem: deciding what to show when aviation sources disagree, time out, or charge for the next answer.

My work
Product design, application development, and data integration
Platform
Web
Stack
JavaScript / Mapbox GL JS / Node.js / Fastify / SQLite / REST APIs
Try the interactive demo →
Have a related project? Let’s talk ↗
FlightDetector live airspace map displaying aircraft positions
Live airspace exploration in FlightDetector.
The challenge
Aviation feeds disagree about routes, coverage and the freshness of an answer.
My contribution
The map experience, data integration, caching and budgeted fallback paths.
The result
A working live and historical tracker that keeps unresolved information visible.

A map is the easy part to understand.

FlightDetector brings together live airspace, individual flight details, routes, altitude information, and historical searches. I built it as a personal engineering project to explore the work behind an interface that appears straightforward: put the right aircraft in the right place and explain where it is going.

The difficult part begins when providers disagree. A position feed, a route database, and an aircraft registry describe different pieces of the same event. Their update cycles, coverage, and failure modes do not line up neatly.

Six sources, with specific jobs.

The frontend uses HTML, CSS, vanilla JavaScript, and Mapbox GL JS. A Node.js service built with Fastify coordinates the upstream sources. adsb.lol provides primary live positions, while OpenSky supports fallback positions and historical information.

adsbdb contributes route and aircraft details. OurAirports supplies airport reference data. AirLabs and AviationStack sit behind a budgeted fallback path. SQLite stores archived records and coverage information, alongside an in-memory cache for answers that only need a short lifetime.

A plausible destination can still be wrong.

One route conflict involved a Southwest flight number assigned to different destinations by different databases. The aircraft's actual movement pointed elsewhere. Reused flight numbers meant that a provider could return a perfectly plausible route for the wrong leg.

I checked claimed routes against observed departure and direction evidence, rejecting candidates that contradicted the aircraft's movement. When the available evidence cannot establish a destination, the interface leaves that uncertainty visible. A confident-looking label should not conceal an unresolved conflict.

Keep what is useful. Fetch what is missing.

Positions change quickly, routes change less often, and airframe records can remain useful much longer. Different cache lifetimes match those differences. Giving every response the same expiration would either make the interface stale or spend requests refreshing information that had barely changed.

A durable archive solves a different problem. Retrieved history can answer future searches, while a coverage index identifies the gaps that still need an upstream request. Monthly database counters check fallback budgets before metered requests are made, keeping cost control inside the request path.

A fallback has to exist before the timeout.

The escalation order starts with information already held, then tries less expensive sources before using metered services for unresolved questions. That order makes provider choice an explicit part of the backend instead of scattering fallback decisions through the map interface.

A live-feed timeout put that approach to use: an existing fallback kept data flowing to the map. It reinforced a practical lesson for this project. Supporting a second provider means deciding when to switch, what evidence remains valid, and how to keep incomplete answers understandable.

Useful exploration, with honest boundaries.

The result is a working interface for exploring live and historical flight information, backed by deliberate decisions about trust, storage, and request budgets. The engineering interest is in how those decisions interact: an archive can reduce repeated work, but it cannot make contradictory evidence true.

FlightDetector is a personal tracking and data-integration project. Source coverage and freshness still determine what it can show. It is not intended as an operational navigation system, and an unknown route remains a valid outcome when the available feeds cannot resolve it.

How it fits together.

  1. 01

    Observe

    Collect positions and reference data from sources with distinct responsibilities.

  2. 02

    Resolve

    Check route claims against movement, cached evidence, and fallback budgets.

  3. 03

    Explore

    Present the map and history while leaving unresolved information visible.

Next project
Kalamna

Got a good problem?

Tell me what you’re building—or what needs to work better.

Start a project ↗