Anatomy of the GitHub globe

For the new GitHub homepage, the product team wanted to show how open source collaboration crosses borders. Their solution centers on a real-time visualization of pull request activity across the globe. The design goals were threefold: show an interconnected community (pull requests opened in one location and merged in another), ground the visualization in real work happening at that moment, and keep the experience fast and visually clean across devices. That last constraint shaped much of the engineering.

The globe runs in a WebGL context powered by three.js. It takes a JSON feed of recent pull requests and renders them in a five-layer scene: a halo, the globe, the Earth's regions, blue spikes for open pull requests, and pink arcs for merged pull requests. The globe itself uses no textures. Four lights point at a sphere, and roughly 12,000 five-sided CircleBufferGeometry instances form the landmasses. A custom shader draws a halo on the backside of a slightly larger sphere.

Mapping land with instanced geometry

Drawing the Earth's regions starts with a density value for the circles you want to place. A nested loop walks longitudes and latitudes from the south pole upward, calculating the circumference at each latitude and distributing circles evenly along it. Whether a circle lands on land or water is determined by loading a small PNG world map and reading its alpha channel with context.getImageData(). The visibilityForCoordinate(long, lat) method maps each circle to a pixel; if the alpha is at least 90 out of 255, the circle is drawn, otherwise it is skipped.

Once the visible circle positions are collected, they are rendered through a single InstancedMesh of CircleBufferGeometry instances rather than thousands of individual meshes.

Finding your location without a lookup

When the homepage loads, the globe should appear centered nearby if possible, but without stalling the first frame behind an IP geolocation call. The compromise is a coarse but instant estimate: the globe's starting angle centers over Greenwich, then Date.getTimezoneOffset() provides the device's offset, which is converted to radians and applied as a rotation around the globe's axis. It is not an exact location, but done fast enough to keep the initial render snappy.

Rendering pull requests

The animated arcs between merged pull requests are the centerpiece. Each merged PR record carries two locations: where it was opened and where it was merged. Those points are mapped to the globe, and a bezier curve is drawn between them. The curves are placed on one of three orbits; the greater the distance between points, the further out into space the arc is pulled.

Geometry is generated along these paths with TubeBufferGeometry. That allows the team to use setDrawRange() to animate the line growing from its origin to its merge point. When an arc reaches its destination, two effects play: a solid circle stays at the merged location while the line is visible, and a ring scales up and fades out. The easing on these animations follows a simple formula—each frame steps 6% closer to the target scale, accelerating naturally as it hits the destination.

Optimizing for devices that can't antialias

Performance targets led to a decision early on: antialias stays off. Many modern machines could render the globe at 60 FPS with antialias enabled, but lower-powered devices could not, and the team prioritized smooth performance across the board. The side effect was a jagged, pixelated edge where the globe's lit rim met the dark background.

The visual fix was also a performance win. A custom shader draws a gradient on the backside of a sphere slightly larger than the globe, tilted to emphasize the glow in the top left. This halo masks the aliased edge at a fraction of the cost of full-scene antialiasing.

Antialiasing off also produced a visible moiré pattern, as the small landmass circles compressed toward the globe's edge. The team reduced that artifact with a fragment shader that fades each circle's alpha based on its distance from the camera, simulating a thicker atmosphere and softening the interference pattern.

Making the loading state feel instant

The composition of the homepage needs to look balanced even before WebGL initializes. To prevent an empty placeholder, the team designed a bare version of the globe using only gradients in Figma and exported it as an SVG, embedded directly in the HTML. It adds negligible overhead and guarantees that something convincing appears immediately.

As soon as the first WebGL frame is ready, the SVG and canvas crossfade while both scale up slightly, using the Web Animations API. This avoids touching the DOM during the transition, which keeps the swap as stutter-free as possible.

Quality tiers for graceful degradation

Maintaining 60 FPS across thousands of device and browser combinations required building in a fallback system. The globe monitors its achieved frame rate continuously; if it fails to hold 55.5 FPS over the last 50 frames, it starts shedding load.

Four quality tiers exist. Dropping down a tier reduces expensive calculations: pixel density, raycasting frequency for hover detection, and the amount of on-screen geometry. Reducing geometry brings the system back to the landmass density: as the tier falls, the desired circle density is lowered and the Earth's regions are rebuilt from approximately 12,000 circles down to about 8,000.

The globe is one piece of a larger redesign effort spanning design, brand, engineering, product, and communications teams at GitHub. Later installments in this series cover the data pipeline feeding the globe, how the page reaches high performance in delivery, and how the site's illustrations and narrative were developed.