A visually distinctive flight tracker with a vintage airline aesthetic. Track any flight in real time using live ADS-B data from receivers worldwide.
┌──────────────────────────────────────────┐
│ Frontend (Vite + React) │
│ ┌─────────┐ ┌──────────┐ ┌───────────┐ │
│ │SplitFlap│ │ Boarding │ │ MapLibre │ │
│ │ Display │ │ PassCard │ │ GL Map │ │
│ └─────────┘ └──────────┘ └───────────┘ │
│ ┌──────────┐ ┌──────────────────────┐ │
│ │ Cockpit │ │ Passport Stamps │ │
│ │ Gauges │ │ (Flight History) │ │
│ └──────────┘ └──────────────────────┘ │
│ TanStack Query (8s polling) │
└──────────────┬───────────────────────────┘
│ /api/flights/*
┌──────────────┴───────────────────────────┐
│ Backend (Express.js) │
│ ┌───────────┐ ┌─────────────────────┐ │
│ │ ADSB.lol │ │ Enrichment Layer │ │
│ │ Proxy │ │ (Airline/Aircraft │ │
│ │ │ │ local database) │ │
│ └─────┬─────┘ └─────────────────────┘ │
└────────┼─────────────────────────────────┘
│
┌────────┴────────┐
│ ADSB.lol API │
│ (Free, no key) │
└─────────────────┘
- Split-Flap Departure Board — Mechanical flip animation on the header
- Boarding Pass Layout — Physical ticket design for flight cards with perforated edges
- Cockpit Gauges — Analog instruments showing altitude, speed, heading, vertical rate
- Live Map — MapLibre GL with rotated aircraft marker and auto-tracking
- Passport Stamps — Collect tracked flights as vintage passport stamps
- Real-Time Polling — TanStack Query polls every 8 seconds for live updates
- Smart Search — Handles IATA codes (EK203), ICAO callsigns (UAE203), registrations (A6-EWA)
- 50+ Airlines — Built-in airline enrichment database for names and country codes
- 20+ Aircraft Types — Local database with aircraft names, categories, seat counts
- Warm Retro Palette — Cream, ink black, vermillion red, teal accents (no dark-mode radar)
# Clone or copy the project
cd skypulse
# Start everything
docker-compose up --build
# Open in browser
open http://localhost:5173That's it. No API keys needed for core functionality.
cd backend
npm install
npm run dev
# Runs on http://localhost:3001cd frontend
npm install
npm run dev
# Runs on http://localhost:5173 with proxy to backend| Endpoint | Description |
|---|---|
GET /api/flights/search?q=EK203 |
Smart search (tries callsign, reg, IATA conversion) |
GET /api/flights/callsign/UAE203 |
Direct ICAO callsign lookup |
GET /api/flights/hex/a12345 |
ICAO 24-bit hex code lookup |
GET /api/flights/reg/A6-EWA |
Registration / tail number lookup |
GET /api/flights/type/A388 |
All aircraft of a type currently airborne |
GET /api/flights/area?lat=25.25&lon=55.36&dist=50 |
Aircraft in radius (nautical miles) |
GET /health |
Health check |
The app works fully without any API keys. For enriched data, you can add:
# Copy the example env file
cp .env.example .env
# Add optional keys (both have free tiers)
AVIATIONSTACK_API_KEY=your_key_here # 100 req/month free
AIRLABS_API_KEY=your_key_here # 1000 req/month freeADSB.lol is a community-run ADS-B aggregator providing:
- Completely free, no authentication required
- Unfiltered live aircraft data (including military/government)
- Position, altitude, speed, heading, vertical rate, squawk
- Aircraft type, registration, ICAO hex code
- ~5 second position update resolution
The only limitation: aircraft must be currently transmitting ADS-B signals to be visible. Flights that haven't departed yet or are outside ADS-B receiver coverage won't appear.
| Layer | Technology | Purpose |
|---|---|---|
| Frontend | React 18 + TypeScript | UI framework |
| Build | Vite 6 | Dev server + bundler |
| Data | TanStack Query v5 | Polling, caching, background refetch |
| Map | MapLibre GL JS | Free WebGL map rendering |
| Tiles | OpenFreeMap | Free vector tiles, no API key |
| Fonts | Playfair Display + DM Mono + DM Sans | Typography |
| Backend | Express.js | API proxy + enrichment |
| Container | Docker + nginx | Production deployment |
| Data | ADSB.lol | Free live ADS-B data |
skypulse/
├── docker-compose.yml
├── .env.example
├── backend/
│ ├── Dockerfile
│ ├── package.json
│ └── src/
│ ├── index.js # Express server
│ ├── routes/
│ │ └── flights.js # API route handlers
│ └── services/
│ ├── adsb.js # ADSB.lol client + smart search
│ └── enrichment.js # Airline/aircraft database
└── frontend/
├── Dockerfile
├── nginx.conf
├── package.json
├── vite.config.ts
├── tsconfig.json
├── index.html
└── src/
├── main.tsx
├── App.tsx # Main orchestrator
├── index.css # Global styles + animations
├── api/
│ └── flights.ts # API client
├── hooks/
│ └── useFlightData.ts # TanStack Query hooks
├── types/
│ └── flight.ts # TypeScript types
└── components/
├── SplitFlap.tsx # Departure board animation
├── BoardingPassCard.tsx # Ticket-style flight card
├── CockpitGauges.tsx # Analog instrument gauges
├── FlightMap.tsx # MapLibre live map
├── SearchBar.tsx # Search with recent history
└── PassportStamps.tsx # Flight history stamps
Popular long-haul flights that are often airborne:
| Flight | Route | Airline |
|---|---|---|
| EK203 | DXB → JFK | Emirates |
| QR901 | DOH → LHR | Qatar Airways |
| BA115 | LHR → JFK | British Airways |
| SQ22 | SIN → JFK | Singapore Airlines (world's longest) |
| LH400 | FRA → JFK | Lufthansa |
| EY101 | AUH → LHR | Etihad |
| TK1 | IST → JFK | Turkish Airlines |
MIT