EarthGuessr runs as a React application built with Vite and TypeScript. React Router selects the page, and game screens keep their display state in React. The database stores sessions and results so a score can be checked independently of what the browser displays.
Two kinds of map rendering
The landing-page globe uses globe.gl and Three.js. The game uses a map component to display satellite tiles and a separate view for choosing a location. These parts have different jobs: displaying the place to inspect and letting the player submit a geographic guess.
The repository includes both MapLibre GL and Mapbox GL dependencies. The satellite raster source in the map component points to Google's tile endpoint. Describing all the imagery as Mapbox imagery would be inaccurate.
A guess goes to a database function
For a standard solo game, the client calls the Supabase start_game function with the selected mode, time limit, and optional location filters. The response supplies a session identifier and the first round's location information.
When a player guesses, the browser sends the session, round number, and guessed coordinates to submit_guess. The function calculates and stores the result. The browser uses the response to update the score and decide whether to advance or show the completed game.
Daily, streak, and knockout play have their own paths. Multiplayer adds shared lobby state and messages about round progress; it is not simply several independent solo games displayed together.
Accounts and multiplayer
Supabase handles authentication and the database connection. The multiplayer entry page requires authentication to create a lobby. The initial lobby request specifies eight players; the lobby settings and database validation govern the final capacity.
Realtime channels notify connected clients about changes and submitted rounds. They also need to reconnect after interruptions. A WebSocket connection alone does not guarantee that every client has the latest state.
The blog is rendered during the build
Vercel runs the prerender command, which compiles the app and launches a local preview. A Playwright browser visits the public routes, and the script writes the rendered HTML into the build output. Blog pages therefore have HTML available before a visitor runs the app's JavaScript.
The script also produces social cards, a sitemap, and a feed. Gameplay routes use the application entry point. The deployment configuration has specific route rewrites, rather than one rule for every URL.
Analytics and checks
PostHog records product events. The authentication code also identifies signed-in users with account properties, so the implementation should not be described as collecting only anonymous session activity. Vercel Speed Insights is included for performance measurement.
TypeScript checks the application before the production bundle is built. Playwright tests exercise browser flows. These checks cover different failure modes; passing a build does not establish that multiplayer works under every network condition.