A live, self-hosted dashboard that tracks any active satellite in real time. Pick a satellite and watch its position, speed, and orbital path update continuously — all computed locally with real orbital mechanics, not a third-party tracking API.
Live https://utkarsh094.github.io/satellite-tracker/
- Tracks any satellite in a selectable Celestrak group (ISS, Tiangong, and other active objects) in real time
- Computes live latitude, longitude, altitude, and orbital speed updated every couple of seconds
- Calculates Azimuth/Elevation relative to a fixed ground location, the same math a real antenna tracker would use to point at the sky
- Displays the satellite's raw orbital elements (inclination, eccentricity, RAAN, mean motion)
- Gracefully falls back to cached data if the upstream data source is temporarily unreachable, instead of failing outright
Under the hood, this is a small full-stack system with a clear separation between orbital computation and presentation:
Celestrak (orbital element data)
│
▼
Backend — Python, Flask, Skyfield
• fetches & caches TLE data (respects Celestrak's refresh limits)
• SGP4 propagation → real-time satellite position
• converts geocentric position → observer-relative Az/El
│
▼
REST API (Flask, hosted on PythonAnywhere)
│
▼
Frontend — plain HTML/CSS/JS (hosted on GitHub Pages)
• satellite picker, live stat panels
The backend fetches orbital element sets (TLEs) from Celestrak and caches them locally, since the underlying data itself only updates a few times a day — no need to hit the API more often than that. When a satellite is selected, the backend runs SGP4 propagation via the Skyfield library to compute its exact position for the current moment, then converts that into azimuth/elevation relative to a fixed observer location. This is exposed through a small Flask REST API that the frontend polls every couple of seconds to keep the display live.
| Layer | Technology |
|---|---|
| Orbital propagation | Skyfield (SGP4) |
| Backend API | Python, Flask |
| Data source | Celestrak GP/OMM data |
| Frontend | Plain HTML, CSS, JavaScript |
| Backend hosting | PythonAnywhere |
| Frontend hosting | GitHub Pages |
The backend and frontend are deployed independently, on separate platforms, and communicate purely over a REST API:
- Backend runs on PythonAnywhere, chosen specifically because its free tier stays continuously running (no cold-start sleep), which matters for a dashboard people might check at any time of day.
- Frontend is static and deploys automatically from this repo via GitHub Pages on every push to
main. - CORS is explicitly restricted on the backend to only accept requests from the deployed frontend's origin, not left open to any site.
- Backend updates are deployed manually (
git pull+ reload on PythonAnywhere) rather than auto-deployed, since the platform's free tier doesn't support push-to-deploy a deliberate tradeoff in exchange for reliable always-on hosting.
- Why not just call a live tracking API? The orbital math (SGP4 propagation) is done directly in this project rather than proxying another tracking service — the backend only depends on Celestrak for the raw orbital elements themselves, everything else (position, Az/El, orbit shape) is computed locally.
- Type safety across the Python↔JSON boundary: Skyfield's underlying numeric types (NumPy floats/booleans) aren't natively JSON-serializable, so every value returned by the API is explicitly cast to a native Python type before being sent to the frontend.
- Resilience: if Celestrak is temporarily unreachable, the backend falls back to the most recent successfully cached data rather than returning an error, so a brief upstream outage doesn't take the dashboard down with it.
| Endpoint | Description |
|---|---|
GET / |
Health check |
GET /satellites |
List of trackable satellites in the current group |
GET /track?sat=<norad_id> |
Full live tracking data for one satellite, including orbital elements |
git clone https://github.com/utkarsh094/satellite-tracker.git
cd satellite-tracker
python3 -m venv venv
source venv/bin/activate #for MAC/Linux
Windows: venv\Scripts\activate #for windows
pip install -r backend/requirements.txt
cp backend/.env.example backend/.env # then fill your coordinates here.
cd backend
python app.pyIn a separate terminal:
cd docs
python -m http.server 5500Visit http://localhost:5500.
This project has already benefited from real external contributions — caught bugs, performance improvements, and cleaner code from outside review. Issues and pull requests are genuinely welcome, whether that's a bug fix, a performance improvement, or a new feature.