I rendered a real airport from open data in plain three.js
Tashkent International, drawn to scale from OpenStreetMap: both runways with their painted markings, the terminals, and a night lighting rig that comes up on the city's own clock. No game engine, no database, no key in the request path. The airfield sibling of the Grove map.
Tashkent International is a real airport with a real layout, and like most of the built world, its geometry is published as open data. I wanted to know what would happen if I fed that data to plain three.js instead of a game engine: no scene editor, no asset store, no server, just coordinates and a projection. What came back was the field to scale, both runways with their painted markings, the terminals, and after dark a lighting rig that comes up on the city's own clock.
One airport, entirely from open data
Everything on screen comes from OpenStreetMap. The runways, taxiways, aprons, and terminal footprints are all tagged geometry that anyone can download. I fetch it once, commit the result as a static artifact, and render from that. There is no database and no API key in the request path. The airport cannot go down, because there is nothing live to go down; the scene is a committed file and a projection.
The recipe, borrowed from a village
The technique is not new here. It is the same recipe behind the Grove parcel model: open-data footprints, a pure equirectangular projection from latitude and longitude into meters, and plain three.js. For the village, building footprints extrude to their tagged heights. For the airport, the same code does something slightly different: runway and taxiway centerlines become ribbon geometry at their real tagged widths, and terminal footprints extrude as before. I did not write an airport renderer. I pointed a footprint renderer at an airport, and the parts that differ are a handful of tags.
Ribbons and extrusions
A runway in the data is a line with a width tag, not a polygon. To draw it as a surface you walk the line and lay a ribbon of the tagged width along it, which gives you the asphalt, the correct proportions, and a centerline to paint. Taxiways are the same primitive at a smaller width. The terminals are closed ways with height tags, so they extrude straight up. Once those two operations exist, most of an airfield is just data flowing through them.
A field that keeps its own clock
The scene defaults to live local time. Uzbekistan sits at UTC+5 year-round with no daylight saving, so the offset is a fixed number and I need no timezone database, just arithmetic. Open it during the day there and it is day; open it after dark and the field lights up. Night is not a hard toggle but a smooth amount with dawn and dusk ramps, so the sky, the runway lights, and the lit windows of the city behind all crossfade together.
The night rig
The lighting is where a plan drawing becomes a place. Runway edge lights run down both sides. A green bar marks the threshold. A PAPI sits beside it showing two white over two red, the picture a pilot reads as on the glideslope. And the approach lights carry the sequenced flasher the controllers call the rabbit: a strobe that runs up the centerline toward the threshold, one flash chasing the next. None of it is decoration. Each light is a real fixture with a real job, placed where the data says it sits.
Ride the landing
Because the geometry is real, the camera can use it. One mode puts the view behind an arriving aircraft for the whole final approach: down the glideslope, over the threshold, touchdown, rollout, and a hand back to the overview, while a second aircraft climbs out from the parallel runway. It is a small thing that only works because the runway is where the runway actually is.
When a committed artifact beats a live feed
The honest trade-off is staleness. Because the data is committed rather than fetched, the scene is only as current as the last refresh, which I do by hand on a slow cadence. For a working navigation tool that would be a bug. For this, a faithful model of a fixed piece of infrastructure, it is the right call: airports do not move, the payoff is a scene with zero runtime dependencies, and the cost is a manual refresh a few times a year. Building it also flushed out a real bug elsewhere, a mobile hydration mismatch hiding in shared layout code, which is the sort of thing a new rendering surface tends to surface. I would reach for a live feed the day this needs to show traffic that is actually flying. It does not, so I did not.
Get the next one
An occasional note when something genuinely new ships here — essays, free tools, projects. No schedule, no filler, easy out.
Need something like this built?
I design and ship AI tools, full-stack apps, and data pipelines — end to end, to production. Tell me the problem in a sentence; I'll give you an honest read on fit within a day.
Work with me →