SpaceX-Launch-Tracker: SpaceX Launch Tracker: How a Tiny Favorites Layer Turns a Public API Into a Personal Mission Control

A React and Node app that keeps the SpaceX feed public, keeps user data minimal, and uses just enough backend logic to make the experience feel tailored.

8 min read View on GitHub More from Aryanchaudhary0

A wide mission room where a public launch feed pours in from the left as stacked printouts and panels, while a small personal ledger is clipped onto the stream on the right. The image explains how the app turns a shared API into an owned experience with only a thin private layer.
The app does not replace the SpaceX feed. It adds a small private layer that makes the public data feel claimed and personal.
Key Takeaways

The interesting move here is not the SpaceX data. It is the tiny private layer wrapped around it. SpaceX Launch Tracker lets a user favorite launches, then stitches that personal state back onto a public API so the experience feels owned without copying the whole universe into its own database.

SpaceX Launch Tracker: Stay up-to-date with the latest and past SpaceX launches.

Aryan Chaudhary, Project Creator · Project README

The real product is not the launch feed

Most launch trackers are variations on the same idea: fetch missions, render cards, add filters. This one is different because it gives the user a way to say, in effect, "this launch matters to me." That is a small product decision with a large effect. The feed stops feeling like a catalog and starts feeling like a collection.

That is why the favorites feature matters more than the rocket data. It turns a generic dashboard into a personal mission control panel, and it does it with almost no extra surface area.

A minimal backend that only stores what it must

The backend behaves like a personalization service, not a warehouse. It keeps user accounts, JWT auth, and a small favorites record that stores only what is needed to reconstruct intent later: a user, a launch, and a bit of metadata for display.

The app keeps the public feed public. Favorites are a thin overlay that is merged back into the UI when needed.

favoriteSchema.index({ userId: 1, launchId: 1 }, { unique: true });

const { data: rocket } = useFetch(
  launch?.rocket ? `https://api.spacexdata.com/v4/rockets/${launch.rocket}` : null
);

That unique compound index is the kind of detail that quietly makes the whole product feel disciplined. It prevents duplicate favorites at the database level, so the app can stay simple everywhere else. The frontend then reads like a projection of two sources, not a pile of stateful exceptions.

A close-up split-screen monitor where one side shows a deep-space visual layer and the other shows a red Mars-toned layer, connected by a single toggle. The image explains how theme state changes the app's atmosphere, not just its colors.
The theme switch does more than restyle buttons. It changes the emotional register of the whole interface.

How the app fetches one thing, then the next

The data flow is deliberately reactive. A launch detail page fetches the launch first, then conditionally fetches the related rocket only if the first request returns a rocket ID. That keeps the code small, but it also avoids guessing about downstream data before it exists.

The custom `useFetch` hook centralizes loading and error state, so the rest of the UI can stay focused on composition. In practice, that means the app is not over-engineered, just well partitioned.

ApproachWhat happensTrade-off
Naive fetch-allPull launch and rocket data together up frontSimple, but wastes requests and makes dependency chains harder to reason about
Reactive fetchFetch the launch first, then fetch the rocket only if neededSlightly more logic, much cleaner data flow

That pattern matters because launch data is nested and uneven. Reactive fetching keeps the interface honest about what it knows and when it knows it.

The UI is doing product work, not decoration

The dual-video background and theme context are not just style flourishes. They make the app feel like a place with a point of view. Dark mode reads like deep space. Light mode reads like Mars. The interface is doing branding through state.

That matters because the app is small. A large product can lean on breadth. A compact one needs atmosphere, and this repo gets that from a few well-placed visual decisions.

This sits between a demo and a real product

Compared with the raw SpaceX API, this repo adds interpretation. Compared with more polished launch products, it stays narrow and teachable. That is its lane: a clean example of how to personalize a public feed without turning it into a sprawling platform.

LayerData sourcePersonalizationUI polishScope
SpaceX APIPublic launch dataNoneNoneSource only
This repoSpaceX API plus private favoritesLightweight user overlayStrong for a small appFocused and readable
Next SpaceflightMultiple data sources and product curationHighHighBroad and feature rich

The point is not to beat bigger launch apps at their own game. The point is to show how a public data feed can become personal with a minimal backend, a disciplined fetch strategy, and a visual system that knows exactly what story it is telling.