All projects

Project breakdown · Active Project

AstraScope

A full-stack project for exploring satellites, orbital passes, near-Earth objects, and atmospheric fireball data through an interactive 3D interface.

ReactTypeScriptThree.jsFastAPIPython

Why I built it

I wanted to turn difficult-to-read public space datasets into something visual while learning how a frontend, API, calculations, and external data sources fit together.

What works today

Satellite filtering, observer-based pass predictions, ground tracks, coverage footprints, near-Earth object data, and fireball data work today. A public frontend is available, with the API deployed separately.

What I wanted to learn

  • Build a data-heavy 3D interface with React and TypeScript.
  • Design a FastAPI boundary around public-data aggregation and caching.
  • Work with orbital data, caching, fallbacks, and automated tests.

How it works

  1. Propagate satellite positions with SGP4/SDP4 and render spacecraft with GPU instancing.
  2. Use CelesTrak catalog data with a SatNOGS fallback and NASA/JPL near-Earth datasets.
  3. Provide filters, observer location, pass predictions, ground tracks, and coverage footprints in one focused interface.

Technical structure

React and TypeScript use satellite.js in the browser for SGP4/SDP4 propagation, ground tracks, and observer-based pass predictions. React Three Fiber renders the results with Three.js instanced meshes. FastAPI aggregates and normalizes public catalogs, joins metadata by NORAD ID, and provides cached NASA/JPL feeds. Orbital records and catalog-only metadata stay separate so objects without current elements are not assigned invented positions.

Data flow

  1. Public sources

    CelesTrak orbital records and SATCAT metadata; SatNOGS fallback; NASA/JPL near-Earth and fireball feeds.

  2. FastAPI

    Normalize records, preserve provenance, cache responses, and expose catalog and Impact Watch endpoints.

  3. React + satellite.js

    Fetch records, propagate orbital positions, and calculate ground tracks and passes for the selected observer.

  4. Three.js

    Render instanced satellite markers and overlays; React supplies filters, details, and the local Watchlist.

Testing

  • Frontend Vitest files cover orbital utilities, API helpers, storage, Watchlist backup, and Impact Watch behavior.
  • Backend pytest files cover catalog and Impact Watch behavior. GitHub Actions runs backend tests, frontend tests, lint, and a frontend production build.

Deployment

The repository separates a Vite frontend deployed to Vercel from a FastAPI service configured for Render. VITE_API_BASE_URL connects the browser to the API; CORS allows the frontend origin. Provider credentials remain backend-only. Optional Space-Track configuration can expand the orbital catalog.

Technical decisions

  • Use GPU-instanced rendering so spacecraft share geometry and materials.
  • Keep orbital calculations in a frontend utility module, separate from rendering; the API owns upstream-data access and normalization.
  • Cache orbital downloads for two hours and persist the last successful catalog so upstream failures do not immediately empty the interface. Cache SATCAT metadata separately for 24 hours and Impact Watch responses in memory for 15 minutes.

Challenges

Keep the 3D interface responsive while presenting several kinds of time-sensitive data clearly and communicating the limits of public orbital information.

What I learned

This project has strengthened my understanding of coordinating asynchronous data, keeping calculation logic separate from presentation, testing across frontend and backend boundaries, and documenting the limits of source data.

What I'd improve next

Expand automated coverage around upstream-data failures and continue refining performance on lower-powered devices.