skyview: SkyTrack: The Flight Tracker Where the Backend Takes the Blame

A real-time aviation dashboard that turns noisy ADS-B state vectors into a calm, map-first experience by caching, normalizing, and shielding the UI from upstream failure.

9 min read • View on GitHub • More from Kaushar26

A control-room desk sits in front of a flight map while a glass barrier absorbs a storm of raw data slips, rate-limit warnings, and error symbols. The scene explains how the server shields the interface from unreliable upstream data so the map stays calm and usable.
SkyTrack’s real trick is not the map. It is the buffer between a brittle live feed and the UI that depends on it.
Key Takeaways

Most flight trackers show you a map and hope the data cooperates. SkyTrack does the opposite. It assumes the live feed will be noisy, rate-limited, and occasionally wrong, then builds a protective layer around it so the user never has to care.

That is the part worth noticing in Kaushar26/skyview. The project behaves less like a demo and more like a miniature production system: request caching, graceful fallback, normalized payloads, and a frontend that stays simple because the server has already done the hard work.

The map is the least interesting part

This project is in its early stages. Contributions and feedback are welcome.

Kaushar26, Project Author/Maintainer · README.md - Kaushar26/skyview

That README line reads modestly, but the code says something sharper. The interesting move here is not drawing aircraft over a basemap. It is deciding that live aviation data should be treated like an unreliable dependency and wrapped accordingly.

That changes the product. Instead of letting the browser talk directly to OpenSky and fail in public, SkyTrack routes requests through a backend-for-frontend layer that can cache, normalize, and recover. The result feels live without pretending the source is perfect.

How SkyTrack protects the UI from a brittle API

PatternData flowFailure behaviorUI complexityUser experience
Direct client fetchBrowser calls OpenSky directlyRate limits and API errors surface immediatelyHigh, because every component handles its own failuresJittery and fragile
SkyTrack middleware + cacheBrowser calls Express, Express calls OpenSkyServer can reuse cached data or normalize responsesLower, because the frontend receives shaped dataCalm and predictable
SkyTrack with stale fallbackBrowser gets the last useful version when the source breaks429 and 502 become degraded service instead of a dead endStill low, because failure stays centralizedFeels live even under stress

The backend centers on `openSkyService.js`, where an in-memory `Map` acts as the first line of defense. If the same bounding box was just requested, the server can answer without hitting OpenSky again. If the upstream API rejects the call, the server can still return stale data instead of collapsing the whole experience.

That is a production pattern, not a portfolio flourish. It is also the right one for this problem. Real-time data is only useful if the interface keeps its composure when the source does not.

Raw state vectors become readable flight objects

OpenSky does not hand back cozy JSON with friendly field names. It returns dense state vectors, which are compact for machines and unfriendly for humans. SkyTrack’s `flightMapper.js` turns that into something you can actually build a product on.

const [
  icao24, callsign, originCountry, timePosition, lastContact,
  longitude, latitude, baroAltitude, onGround, velocity,
  trueTrack, verticalRate
] = state;

return {
  icao24,
  callsign: callsign?.trim() || null,
  originCountry,
  position: { latitude, longitude },
  altitude: metersToFeet(baroAltitude),
  speed: msToKnots(velocity),
  trueTrack,
  verticalTrend: verticalRate > 0 ? 'climbing' : verticalRate < 0 ? 'descending' : 'level'
};

That mapping step matters more than it looks. It is where the product gets its shape: units become legible, fields get names, and the UI stops asking the frontend to guess what a number means. In practice, this is how raw telemetry becomes a dashboard.

Why the frontend feels fast even while it keeps polling

`useFlights.js` keeps the interface on a steady 15-second rhythm. It also uses `AbortController` so a stale request can be canceled when the user switches regions, which avoids the classic race where the wrong response arrives last and wins.

That detail is easy to miss, but users feel it immediately. The UI does not flicker between regions, and it does not fight its own state. It just updates.

The map is doing more than drawing markers

A close mechanical view shows a single aircraft marker being rotated, fitted into a viewport, and followed by a short breadcrumb trail. The image explains how the map surface combines orientation, auto-fitting, and history into one coherent live view.
SkyTrack’s map does not just display aircraft. It keeps re-composing the scene around them.

In `FlightMap.jsx`, the useful idea is not the basemap itself. It is the behavior layered on top of it. `FitToFlights` keeps the viewport honest, and `createAircraftIcon` turns each plane into a CSS-driven marker that rotates with `trueTrack`.

That makes the map feel alive without adding visual noise. The interface is doing just enough choreography to keep the user oriented, and no more.

The breadcrumb trail is the cleverest visual trick

Because the backend is stateless, the memory lives in the client. `useFlightTrails.js` keeps a short history of positions, checks whether the aircraft actually moved, and caps each trail at eight points. That is enough to imply direction without turning the map into spaghetti.

It is a small piece of design with an outsized effect. SkyTrack gives motion a memory, but only a little one.

Why this is a better portfolio project than the usual dashboard

Typical dashboardSkyTrack
Fetches live data and hopes the API stays availableWraps the upstream source in cache, fallback, and normalization
Pushes failure handling into the browserCentralizes failure handling in a server layer
Shows a map with markersShapes the data, manages polling, fits the viewport, and preserves trails
Looks interactiveBehaves resiliently

That is why this repo stands out. It is not trying to win on feature count. It is solving the annoying parts that usually get ignored: rate limits, stale data, request cancellation, unit conversion, and display logic that does not fall apart under load.

A lot of portfolio projects demonstrate that someone can wire up a stack. SkyTrack demonstrates that someone understands how a live product fails, and how to keep it useful when it does.