No libraries
One file, one canvas, one WebGL2 context. No scene graph, no maths library, no loader, no build step. The only external code is a public-domain simplex noise implementation, pasted into the shader source where it is used.
Showing (UTC)
Drag to orbit. Wheel to zoom. Click a body to fly to it.
This is not a recorded loop. It is the solar system as it stands at the moment you loaded the page: eight planets, the Sun and the Moon solved from the JPL element tables, checked against JPL Horizons, with the worst planet 0.074 degrees out of position. Nothing you can see is a photograph. There are no textures to download.
Nothing above was recorded once and replayed. Every position on screen is solved from published elements at the moment you look at it.
The eight planets come from the JPL/Standish table of Keplerian elements for approximate positions of the major planets: six elements at J2000 plus one rate per Julian century, valid from 1800 to 2050. Kepler's equation has no closed form, so it is solved by Newton iteration, per planet, per frame. Nothing is interpolated between stored keyframes, because there are none.
The Moon is the exception. It uses a truncated Meeus series from Astronomical Algorithms, then gets rotated out of the mean equinox of date into J2000, because that series is of-date and the planet elements are not. Two decades of precession comes to about a third of a degree, which is too much to leave in on a body this close.
The sky behind it is 3,665 real stars at their J2000 right ascension and declination, rotated into the same ecliptic frame by the J2000 obliquity and placed on a sphere far outside Neptune. Each is sized by its visual magnitude and coloured from its B-V index, so the red ones are red for the reason the catalogue says they are. Fourteen constellations can be switched on as stick figures.
Every body turns on its real axis at its real sidereal rate. Earth once every 23.9345 hours, Jupiter every 9.925, Venus every 5,832.6 and backwards, Uranus tipped 97.77 degrees so it rolls rather than spins. The gas giants are drawn as the flattened ellipsoids they are: Saturn is 9.8 percent wider than it is tall, and that is the shape on screen rather than a sphere with rings hung on it.
Time runs at one day, one month or one year per second, forwards or backwards, or not at all. The now button snaps back to the real current moment. Drag to orbit, wheel or pinch to zoom, click or tap a body to fly the camera to it and open its panel, escape to pull back out.
Every drawing of the solar system is wrong about something, and most of them do not say which thing. This is the list for this one.
The positions are the part that holds up. Checked against JPL Horizons for 2026-09-08 at 00:00 UT, the worst planet is Saturn at 0.074 degrees of heliocentric longitude, and the Moon is 110 km out. That is accurate enough to point at a planet with and nowhere near accurate enough to navigate to one, which is the correct amount of accuracy for a web page.
The sizes are the part that lies. In compressed scale, the default, both distances and radii are raised to a power: Neptune's real 30.07 AU is drawn at 4.2 times Earth's orbit. Switch to true distances and the orbits become honest AU while the bodies stay swollen, and the readout prints the factor: about 700 times for Earth. Because size runs on a 0.42 power rather than a straight multiplier, small bodies are flattered more than large ones, roughly 1,230 times for Mercury against about 170 for Jupiter. True size is the correct mode. It is also a black screen with a few dots in it, and that is the argument the mode exists to make.
There are no photographs and no textures. Not one image is downloaded for any body. Every surface is noise evaluated in the fragment shader, so Earth has the right amount of land in the wrong places, Jupiter has the right number of bands and none of the real ones, and Mars has polar caps in the right latitudes and whatever outline the noise produced. If you go looking for a familiar coastline you will not find one.
Every star is real. Until 11 September 2026 only 232 of them were: behind those sat 2,400 invented faint ones from a fixed seed, because a sky holding only the brightest catalogue reads as a bug rather than as a sky. They were replaced by 3,433 measured entries between magnitude 5.0 and 6.0 from the HYG Database 4.1 - the same fix, without the lying. The Moon's orbit is lifted well past its scaled distance in the two diagram modes, or it would sit inside Earth. The Sun's corona is an additive shell out to 5.5 radii, and the bloom is a look rather than an optical model.
The elements stop being valid outside 1800 to 2050. At one year per second you are past the end of the table in about twenty-four seconds, nothing on screen says so, and the planets keep moving while quietly ceasing to be where they would be. The orbit rings are drawn from the J2000 ellipses rather than re-derived while you scrub time, which makes them the one thing on screen that lags the bodies travelling on them.
No framework, no build step, no textures, no package to install. One file and a browser.
The whole scene is 2,106 lines in a single JavaScript file: 81 KB of source plus an 8 KB bright-star table, with a 90 KB catalogue of faint ones alongside it, 64 KB gzipped between them. There is nothing to compile, so the file the browser runs is the file in the repository.
If WebGL2 is missing the model is not drawn at all, and the space it would have filled says why. If the visitor has asked for reduced motion it is drawn once and holds still until they take hold of it. Nothing else on the page changes. Every word here, the ten panels included, sits in the HTML rather than being injected by the script, so the page reads the same with JavaScript blocked outright.
One file, one canvas, one WebGL2 context. No scene graph, no maths library, no loader, no build step. The only external code is a public-domain simplex noise implementation, pasted into the shader source where it is used.
There is one sphere mesh and one planet program; a kind uniform picks the surface and the rest is colour and frequency. Eleven bodies, eleven draws, plus one for the corona shell and one for Saturn's rings. The flattening of the gas giants is a scale on the model matrix, not a second mesh.
Bands, craters, continents, cloud decks and dust are all evaluated per fragment. Nothing is sampled from an image, which means no download, no memory budget and no resolution limit: fly the camera in and the detail keeps resolving, because it is being computed at the size you are looking at it.
A bright pass into a quarter-resolution target, two separable blur passes ping-ponged between two of them, then an additive composite and an ACES-style filmic tone map. It ends with a little ordered dither, because a mostly black page bands visibly at eight bits.
The full sphere is 48 by 96. Below about 26 screen pixels a body swaps to 20 by 40, and below about 30 pixels the three extra noise lookups for surface relief stop being evaluated at all. Nobody can see either change, and the frame budget can.
Device pixel ratio is capped at 1.6 below 820 px and 2.0 above it, so a dense display does not quietly quadruple the shading work. Drag, pinch and tap arrive as pointer events and are read by the same camera as a mouse and a wheel. There is no separate mobile renderer to keep in sync.
Every body in the model has a page of its own. The model is the index; the pages are where the numbers are.
99.86 percent of the mass of the system, 5,500 degrees at the visible edge, and a corona two hundred times hotter than the surface beneath it that nobody has fully explained.
See the page →Smaller than two of Jupiter's moons, 430 degrees at noon, and water ice sitting in craters that have never seen daylight.
See the page →464 degrees at the surface, 92 atmospheres of pressure, and a day longer than its year. The descent runs as one sticky column.
See the page →The atmosphere drawn to true scale against the planet's radius, where Everest and a cruising airliner land on the same hairline.
See the page →A quarter of a million miles, twelve people, 382 kg brought back, and a drift of 3.8 cm further out every year.
See the page →Half the size of Earth, a day 39 minutes longer than ours, two moons, and Olympus Mons. The template the other nine pages came from.
See the page →Ninety percent hydrogen and ten percent helium, 95 confirmed moons, and a composition chart drawn from the same number the counter reads out.
See the page →274 confirmed moons, a ten-hour day, and ring geometry built from a rotated bordered ellipse in CSS rather than an image.
See the page →Tilted 97.8 degrees, and the best photograph ever taken of it from close range is a blank circle. The page prints the blank circle.
See the page →Found by mathematics before anyone pointed a telescope at it. 30.07 AU out, 164.8 years to the orbit, winds at 2,100 km/h.
See the page →