Case study · Client

Restor.eco

The Google Maps of nature, for the world's largest network of restoration sites. The first version was slow and buggy, so a small team rebuilt it from scratch. I was the sole architect of the geospatial and data visualisation frontend.

Role
Sole frontend architect, geospatial & data visualisation
Team
A small product team, plus scientists from Restor and ETH
When
2022–2025, remote
Stack
Next.js, React, TypeScript, deck.gl, GLSL, Google Maps, ArcGIS, visx
Recognition
Earthshot Prize finalist, Gold Anthem Award

The product

Restor is a free platform for anyone restoring nature. Landowners, NGOs, companies, governments and researchers draw their site on the map, see its ecological data, from tree cover to biodiversity, and track how it changes over time.

Users include WWF, The Nature Conservancy, Rewilding Europe, the Government of Costa Rica, Salesforce and UBS.

Nature sites
355,000+
Organisations
7,900+
Nature stewards
38,000+
The Restor map: a satellite world map with clustered restoration sites, next to a welcome panel
The map. Every number is a cluster of restoration sites.
A Restor site page: a forestry project in Ethiopia, its boundary outlined on satellite imagery, with photos and project details
A site: a 2,802 ha community forestry project in Ethiopia.

I worked in a small product team of frontend and backend developers, designers, a digital marketer and a product owner, together with scientists from Restor and ETH. Whenever something was geospatial or data visualisation, I usually ended up as the glue between the scientists and everyone else. I studied geodesy, so I could talk projections, resolution and raster data with the scientists. In practice that meant helping shape APIs and interface decisions, and turning a scientific ask into something the developers and designers could understand and build.

Next to that, I worked with the dev team on the rest of the product: authentication, search, the component library, forms, SSR and performance improvements.

Polygon drawer

Problem

I built the first polygon drawer myself during the rewrite, with Google Maps markers for the vertices and polylines for the edges, each its own DOM element. That's fine for a simple shape. But sites on Restor can have up to 20,000 vertices, so 20,000 markers plus 20,000 edges means 40,000 DOM elements, and the browser just gave up.

What I built

So I rebuilt it in WebGL on deck.gl, with three composite layers, one per interaction mode: drawing a new polygon, editing an existing one, and idle. Only the polygon you're actually drawing or editing pays the heavy rendering cost. Self-intersection and overlap checks run in a web worker with Turf.js, and drag state stays out of React entirely.

Result

Sites with complex boundaries, up to 20,000 vertices, can now be edited without freezing or crashing the browser.

Data layers + pixel value inspector

Problem

Restor has 31 scientific data layers from Google Earth Engine, Google's platform for satellite data, from tree cover to soil carbon, each with its own legend and controls. Changing a layer's range or colours made React re-render, and the browser froze. There was also no good way to read the exact value of a single pixel.

What I built

The tiles are greyscale images, where each pixel's brightness stands for a value, like a year or a percentage of tree cover. A custom ShaderBitmapLayer for deck.gl turns that grey into colour on the GPU. The sliders feed straight into the shader, so moving them doesn't re-render React, recompile the shader or refetch tiles.

A tooltip on the map would have clashed with the existing tooltips, so the legend got something like a colour picker instead. On hover, I read that one pixel's grey value back from the GPU and run the same colour gradient on the CPU, so the legend can show exactly where the pixel sits on its scale. I designed the layer panel as well.

Result

Adjusting a layer's range or colours is instant instead of freezing the browser, and you can read the value of any pixel by hovering the legend.

Satellite imagery timelapse

Problem

On Restor you can watch a site change over time, through Esri Wayback, an archive of satellite imagery going back more than a decade. A lot of the people looking are on slow mobile connections, and I didn't want to burn through the data of a farmer in Ghana.

What I built

The viewer runs on the ArcGIS Maps SDK, with one persistent layer per snapshot. Hidden snapshots sit at zero opacity instead of visible: false, so they're never torn down and recreated, and switching is just an opacity flip on tiles the browser already has. On open it only loads the first and last snapshot, the two most likely to be viewed, and hitting play prefetches three ahead.

Result

Switching between loaded snapshots is instant, and Restor's team was pleasantly surprised by how fast it felt. One thing I didn't solve well: a snapshot's date is only correct at the deepest zoom. Zoomed out, the imagery is stitched together from datasets captured at different times, so the date can be wrong. My fix is an admittedly clunky banner that explains this.

Chart composition

Problem

The science team wanted charts for more than 30 ecological metrics, each wired to its own endpoint. A bespoke component per chart was never going to scale.

What I built

The charts are built from eleven primitives on visx (marks, scales, axes, grids and tooltips) that compose as compound components, each with its own isolated state, so axes, tooltips and the rest could be reused across chart types. They're all documented in Storybook.

Result

After the refactor, adding a new chart took about 30 minutes. Those eleven primitives ended up in 100+ distinct charts.

Next case study

Fahsai

Fires, wind and PM2.5 on one map of Thailand's burning season, with an AI explanation for any station on any day. Designed and built solo, with Claude Code as my pair programmer.

Working on something similar?

I'm looking for my next product engineering role on a data- or map-heavy product. Based in Utrecht, working remote.

dev@joostkiens.com