T/T
Back to work

Personal project · 2026

F1 Atlas

Every season. Every race. Every driver.

The F1 Atlas season calendar, completed rounds with podiums above upcoming rounds with circuit outlines

What it is

F1 Atlas is a Formula 1 record book in the browser. It covers every season from 1950 to the latest race. You can follow a season round by round, open a grand prix for results and qualifying, check the drivers' and constructors' championships, look at a driver's season, or open a circuit to see its winners.

I built it with React and data from the Jolpica API, a replacement for the old Ergast API. The app calls that service directly from the browser, without an API key or a backend of my own.

F1 Atlas drivers' standings table with position, driver, nationality, constructor, wins, and points
The drivers' championship shown as a simple table.

The problem

The data exists, but it feels like an archive, not a finished page. A few things got in the way.

I request season results in batches of 100 rows. A batch can end halfway through a race, leaving the rest of its drivers in the next response. The calendar and results also arrive separately, so a past race may not have results yet. Some archive labels need a little work too: "Retired" is easier to scan as DNF, and "Lapped" needs a lap count.

The API can return winners at a circuit, but the summary I wanted to show still had to be calculated from those results.

The decisions

Combining split results

The first response includes the total number of result rows. I use that total to fetch the remaining batches and combine rows with the same race round. The calendar stays in a loading state until they are all ready, so a split response does not leave a race with only part of its results.

Using the calendar to show race state

I compare each race date with today's date in the visitor's local time. Races before today go into the completed section. If the response has no results yet, the podium area stays empty. This is a calendar shortcut: a race held today stays in the upcoming section, even after it has finished. The page does not track the live session.

Making statuses easier to read

Before a finishing status is shown, it goes through a formatter. Drivers on the lead lap keep their gap to the winner. Other statuses are changed to the short labels used on timing screens.

Archive says Screen shows
Retired DNF
Did not start DNS
Disqualified DSQ
Lapped +1 LAP / +N LAPS
Anything unmapped shown as it comes

For lapped cars, the app calculates the lap count from the winner's distance. If a status is not mapped, it is shown as is, so the table does not end up blank.

Building circuit history

I request first-place finishes at the selected circuit across all seasons, fetching more batches when needed. From those results I count the races and different winners, find the first and latest years, and pick the driver with the most wins. The page shows that summary above a table of winners, with the newest race first.

F1 Atlas circuit page for Monza with a winners table and a short summary
Monza's winner list built from filtered race results.

What I would do differently

I would add caching first. Right now, changing the season repeats every paginated request, and each circuit page rebuilds its history from scratch. Old Formula 1 data does not change often, so caching responses would save a lot of repeated work. It would also make the app feel faster when moving between seasons.

I would also improve driver photos. The podium headshots use a fixed list, with three-letter codes for drivers outside it. Driver pages already request portraits from Wikipedia when available. I would try that approach for podiums too, while keeping the code fallback for missing images.

More work on the home page, or the full history on the CV.